如果你想要mutate現有的列表/字典,使用列表/字典理解被認爲是不好的風格,因爲它創建了一個不必要的一次性列表/字典。
準確地說,我說的是以下幾點:
>>> demo = ['a', 'b', 'c']
>>> freqdist = {'a': 0, 'b': 1, 'c': 2}
>>> [freqdist.__setitem__(key, freqdist[key] + 1) for key in demo]
[None, None, None]
>>> freqdist
{'a': 1, 'c': 3, 'b': 2}
正如你所看到的,做你所描述什麼是可能的,但是這不是你應該怎麼做,是因爲
- 它很難閱讀
- 它創建一個未使用的一次性使用清單
[None, None, None]
- 列表解析應該用來建立一個新的列表,你實際上n eed
由於不是每個值都應該增加(只有demo
中的值),所以創建一個字典理解的新字典也很麻煩。
您可以做
>>> demo = ['a', 'b', 'c']
>>> freqdist = {'a': 0, 'b': 1, 'c': 2}
>>> freqdist = {k:v + (k in demo) for k,v in freqdist.items()}
>>> freqdist
{'a': 1, 'c': 3, 'b': 2}
但是,我們有次優運行的複雜性,因爲現在在freqdist
我們爲demo
做一個O(len(demo)
)成員測試每個鍵。
您可以使用set
爲demo
到字典建設的複雜度降低到O(len(freqdist)
),但僅當demo
元素是唯一的。
>>> demo = set(['a', 'b', 'c'])
>>> freqdist = {'a': 0, 'b': 1, 'c': 2}
>>> freqdist = {k:v + (k in demo) for k,v in freqdist.items()}
>>> freqdist
{'a': 1, 'c': 3, 'b': 2}
我不認爲這個解決方案是特別優雅的。
總之,您的for
循環完全正常。唯一的好替代方案是使用您更新Counter
對象:
>>> from collections import Counter
>>> demo = ['a', 'b', 'c']
>>> freqdist = Counter({'a': 0, 'b': 1, 'c': 2})
>>> freqdist.update(demo)
>>> freqdist
Counter({'c': 3, 'b': 2, 'a': 1})
這是我個人使用的解決方案。
使用[計數器](HTTPS: //docs.python.org/2/library/collections.html#collections.Counter)? – asongtoruin
列表理解創建一個新列表。看起來你不想在這裏創建一個列表。 – ikkuh
'for'循環出了什麼問題?列表解析是爲了創建列表,而不是'for'循環的替代;它看起來像你試圖利用副作用。 – roganjosh