[英]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.