python3二维字典更新的问题

本文探讨了使用不同方法更新二维字典的行为差异,特别是在使用defaultdict和普通dict时的区别。通过对比两种更新方式,展示了如何避免类型转换导致的问题,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在使用二维字典的时候,发现了一个有趣的问题, 发现网上对于二维字典的更新方式全是如下方式,其解释也全是因为二维字典的两层key和value之间会混淆

from collections import defaultdict

def addtwodimdict(thedict, key_a, key_b, val):
    adict = thedict.keys()
    if key_a in adict:
        thedict[key_a].update({key_b: val})
    else:
        thedict.update({key_a:{key_b: val}})

那么,使用这种方式,再看一个代码:


from collections import defaultdict


def addtwodimdict(thedict, key_a, key_b, val):
    adict = thedict.keys()
    if key_a in adict:
        thedict[key_a].update({key_b: val})
        
    else:
        thedict.update({key_a:{key_b: val}})
                        
data =[[1000,2,3,2,5,6,7],[1001,4,6,6,3,7,2],[1002,3,6,2,1,6,7],[1003,3,4,6,5,8,0]]

def my_dict(data):
    graph_dict = defaultdict(lambda: defaultdict(lambda: 0))  # 声明一个二维default dict
    for i in range(len(data)):
        val1=data[i][1]
        val2=data[i][2]
        addtwodimdict(graph_dict,val1,val2,data[i][0])
        addtwodimdict(graph_dict,val2,val1,data[i][0])
    return graph_dict


adict= my_dict(data)
print(adict)

输出为:

defaultdict(<function my_dict.<locals>.<lambda> at 0x7fbfa473cbf8>, {2: {3: 1000}, 3: {2: 1000, 6: 1002, 4: 1003}, 4: {6: 1001, 3: 1003}, 6: {4: 1001, 3: 1002}})

可以发现,我们生成的二维字典,声明为defaultdict(lambda: defaultdict(lambda: 0))本来应该是“内层”和“外层”均是default dict的,但是现在只有外层是default dict,因此如果我们执行print(adict[100]), 不会报错keyerror,执行print(adict[100][1000]) 也同样不会报错,因为外层是default dict,所以尽管键100不存在,也不会报错;但是执行print(adict[2][4]) 会报keyerror的错误,因为键[2][4]不存在,且 不是default dict。但是现在为什么在addtwodimdic后,只有外层才是default dict呢?

原因就在于addtwodimdict中,使用了update的更新方式。这种更新方式会使得default dict变回普通的dict, 因此我们如果修改下addtwodimdict函数为:

def addtwodimdict(thedict, key_a, key_b, val):
    thedict[key_a][key_b] =val  #针对default dict,应该这样更新

可以看到,外层和内层均是default dict了,这才是我们想要的结果。这种情况下,无论是print[2][100], 还是print[100],无论键是否存在,均不会报keyerror的错了。至于网上全说二维字典的两层key和value之间会混淆,实际上应该是这全应该是对于普通的dict来说的。

defaultdict(<function my_dict.<locals>.<lambda> at 0x7fbfa473cd90>, {2: defaultdict(<function my_dict.<locals>.<lambda>.<locals>.<lambda> at 0x7fbfa4660d08>, {3: 1000}), 3: defaultdict(<function my_dict.<locals>.<lambda>.<locals>.<lambda> at 0x7fbfa4677c80>, {2: 1000, 6: 1002, 4: 1003}), 4: defaultdict(<function my_dict.<locals>.<lambda>.<locals>.<lambda> at 0x7fbfa4677488>, {6: 1001, 3: 1003}), 6: defaultdict(<function my_dict.<locals>.<lambda>.<locals>.<lambda> at 0x7fbfa4677158>, {4: 1001, 3: 1002})})

如果要使用update来更新二维数组,那么声明的时候就应该声明为普通的字典dict,而且,如果是普通的二维字典dict,只能使用update来更新,使用hedict[key_a][key_b] =val这样的方式会出错。显然,普通的字典,如果输入的键不存在,则返回keyerror,比如:

from collections import defaultdict

def addtwodimdict(thedict, key_a, key_b, val):
    adict = thedict.keys()
    if key_a in adict:
        thedict[key_a].update({key_b: val})
    else:
        thedict.update({key_a:{key_b: val}})
        #thedict[key_a][key_b] =val  #针对default dict
                        
data =[[1000,2,3,2,5,6,7],[1001,4,6,6,3,7,2],[1002,3,6,2,1,6,7],[1003,3,4,6,5,8,0]]

def my_dict(data):
    graph_dict ={}  #尽管是作为二维字典,但是不能写成graph_dict ={{}} 
    for i in range(len(data)):
        val1=data[i][1]
        val2=data[i][2]
        addtwodimdict(graph_dict,val1,val2,data[i][0])
        addtwodimdict(graph_dict,val2,val1,data[i][0])
    return graph_dict

adict= my_dict(data)
print(adict) # 存在
print(adict[100]) #不存在,报错

输出为;

{2: {3: 1000}, 3: {2: 1000, 6: 1002, 4: 1003}, 4: {6: 1001, 3: 1003}, 6: {4: 1001, 3: 1002}}

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-56-f6e50649b40d> in <module>
     31 adict= my_dict(data)
     32 print(adict)
---> 33 print(adict[100])

KeyError: 100


### 二维字典的实现方法 在 Python 中,可以通过嵌套字典(dictionary of dictionaries)的方式实现二维字典结构。这种结构允许通过两个层级的键来访问数据,非常适合需要对两个关键词进行查找的场景。例如,`dict_2d = {&#39;a&#39;: {&#39;a&#39;: 1, &#39;b&#39;: 3}, &#39;b&#39;: {&#39;a&#39;: 6}}` 就是一个典型的二维字典结构,其中外层字典的键 `&#39;a&#39;` 和 `&#39;b&#39;` 分别对应内层字典的键值对集合[^1]。 #### 创建二维字典 可以通过直接定义的方式创建二维字典: ```python dict_2d = { &#39;a&#39;: {&#39;a&#39;: 1, &#39;b&#39;: 3}, &#39;b&#39;: {&#39;a&#39;: 6} } ``` 也可以通过动态添加的方式构建二维字典: ```python dict_2d = {} dict_2d[&#39;a&#39;] = {} dict_2d[&#39;a&#39;][&#39;b&#39;] = 3 dict_2d[&#39;b&#39;] = {} dict_2d[&#39;b&#39;][&#39;a&#39;] = 6 ``` #### 访问二维字典中的值 可以通过外层键和内层键来访问二维字典中的值: ```python print(dict_2d[&#39;a&#39;][&#39;b&#39;]) # 输出: 3 ``` #### 遍历二维字典 可以使用嵌套的 `for` 循环来遍历二维字典中的所有键值对: ```python for outer_key, inner_dict in dict_2d.items(): for inner_key, value in inner_dict.items(): print(f"Outer Key: {outer_key}, Inner Key: {inner_key}, Value: {value}") ``` #### 处理缺失键的情况 为了避免访问不存在的键时引发 `KeyError`,可以使用 `get` 方法: ```python value = dict_2d.get(&#39;a&#39;, {}).get(&#39;c&#39;, None) print(value) # 输出: None ``` #### 示例:存储用户信息的二维字典 以下是一个存储用户信息的二维字典示例: ```python users = { &#39;001&#39;: {&#39;name&#39;: &#39;张1&#39;, &#39;age&#39;: &#39;18&#39;, &#39;address&#39;: &#39;北京&#39;, &#39;房补&#39;: 10000}, &#39;002&#39;: {&#39;name&#39;: &#39;张2&#39;, &#39;age&#39;: &#39;19&#39;, &#39;address&#39;: &#39;湖北&#39;}, &#39;003&#39;: {&#39;name&#39;: &#39;张3&#39;, &#39;age&#39;: &#39;20&#39;, &#39;address&#39;: &#39;北京&#39;, &#39;房补&#39;: 10000} } ``` 可以通过以下方式访问特定用户的详细信息: ```python print(users[&#39;001&#39;]) # 输出: {&#39;name&#39;: &#39;张1&#39;, &#39;age&#39;: &#39;18&#39;, &#39;address&#39;: &#39;北京&#39;, &#39;房补&#39;: 10000} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值