为什么dict.get(key)起作用但dict [key]不起作用?

我正在尝试根据字符串中存在1的数字将二进制数的二进制字符串组合在一起。

这不起作用:

s = "0 1 3 7 8 9 11 15"
numbers = map(int,s.split())
binaries = [bin(x)[2:].rjust(4,'0') for x in numbers]

one_groups = dict.fromkeys(range(5),[])
for x in binaries:
    one_groups[x.count('1')] += [x]

期望的字典one_groups必须

{0: ['0000'],1: ['0001','1000'],2: ['0011','1001'],3: ['0111','1011'],4: ['1111']}

但是我明白了

{0: ['0000','0001','0011','0111','1000','1001','1011','1111'],1: ['0000',2: ['0000',3: ['0000',4: ['0000','1111']}

到目前为止,唯一有效的方法是使用one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x]而不是one_groups[x.count('1')] += [x]

但是为什么会这样呢?如果我没记错的话,dict[key]是否应该返回该字典的值,类似于dict.get(key)的工作方式? 我已经看到了该线程Why dict.get(key) instead of dict[key]?,但是对于这种特殊情况,它没有回答我的问题,因为我确定该程序并不是要获取KeyError

我也尝试过one_groups[x.count('1')].append(x),但这也不起作用。

jiemy666 回答:为什么dict.get(key)起作用但dict [key]不起作用?

问题是可变性:

one_groups = dict.fromkeys(range(5),[])-这会将与值相同的列表传递给所有键。因此,如果更改一个值,则全部更改。

基本上和说的一样:

tmp = []
one_groups = dict.fromkeys(range(5),tmp)
del tmp

如果要使用新列表,则需要循环执行-显式for循环或dict理解:

one_groups = {key: [] for key in range(5)}

该事物将为每个键“执行” [](等于list()),从而使值具有不同的列表。


get为何起作用?因为您显式获取了当前列表,但是+却创建了一个新的结果列表。不论是one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x]还是one_groups[x.count('1')] = one_groups[x.count('1')] + [x]都没关系-重要的是有+

我知道每个人都说a+=b只是a=a+b,但是优化的实现可能有所不同-在列表的情况下,+=只是.extend,因为我们知道我们希望将结果保存在当前变量中,因此创建新列表将浪费内存。

,

问题出在使用one_groups = dict.fromkeys(range(5),[])

(这会将与值相同的列表传递给所有键。因此,如果更改一个值,则全部更改)


您可以改用此方法:one_groups = {i:[] for i in range(5)}

(此操作将为每个键“执行” [](等于list()),从而使值具有不同的列表。)

,

这是dict的fromkeys方法的帮助。

  

关于来自键的内置功能的帮助:

     buildins.type实例的

fromkeys(iterable,value = None,/)方法       使用可迭代键并将值设置为value创建新字典

这表示fromkeys将接受一个值,即使它是可调用的,它也会先对其求值,然后将该值分配给所有dict键。

列表在Python中是可变的,因此它将分配相同的空列表引用,并且一项更改将影响所有列表。

改用defaultdict:

>>> from collections import defaultdict
>>> one_groups = defaultdict(list)
>>> for x in binaries:
      one_groups[x.count('1')] += [x]
>>> one_groups = dict(one_groups) # to stop default dict behavior

这将接受对不存在的键的分配,并且值将默认为空列表(在这种情况下)。

本文链接:https://www.f2er.com/3165817.html

大家都在问