[英]Why did dict.get(key) work but not 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', '0001', '0011', '0111', '1000', '1001', '1011', '1111'],
2: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'],
3: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'],
4: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111']}
到目前为止,唯一有效的是如果我使用one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x]
而不是one_groups[x.count('1')] += [x]
但为什么会这样呢? 如果我没记错的话, dict[key]
不应该返回该字典的值,类似于dict.get(key)
的工作原理吗? 我看过这个线程为什么用 dict.get(key) 而不是 dict[key]? 但它没有回答我针对这种特殊情况的问题,因为我确定该程序并不意味着获取KeyError
我也试过one_groups[x.count('1')].append(x)
但这也不起作用。
问题是可变性:
one_groups = dict.fromkeys(range(5), [])
- 这会将与 value 相同的列表传递给所有 keys 。 因此,如果您更改一个值,则将它们全部更改。
这与说的基本相同:
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
因为我们知道我们希望我们的结果在当前变量中,所以创建新列表将浪费 memory。
问题是使用one_groups = dict.fromkeys(range(5), [])
(这会将相同的列表作为值传递给所有键。因此,如果您更改一个值,则将它们全部更改)
您可以改用它: one_groups = {i:[] for i in range(5)}
(这个东西将为每个键“执行”[](等于 list()),从而使值具有不同的列表。)
这是 dict 的fromkeys
方法的帮助。
内置 function 的帮助来自keys:
fromkeys(iterable, value=None, /) 方法 builtins.type 实例创建一个新字典,其中键来自 iterable,值设置为 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
这将接受分配给不存在的键和值将默认为空列表(在这种情况下)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.