[英]Python 3 - Scope of dict comprehension -> in object -> in list comprehension
[英]Is it possible to access current object while doing list/dict comprehension in Python?
試圖想到一種方法來實現以下目的(將鍵的所有值相加):
>>> data = [('a',1),('b',3),('a',4),('c',9),('b',1),('d',3)]
>>> res = {}
>>> for tup in data:
... res[tup[0]] = res.setdefault(tup[0],0) + tup[1]
...
>>> res
{'a': 5, 'c': 9, 'b': 4, 'd': 3}
一線版,不使用itertools,collection等任何導入。
{ tup[0] : SELF_REFERENCE.setdefault(tup[0],0) + tup[1] for tup in data }
在Python中是否可以使用對當前正在理解的對象的引用? 如果沒有,有沒有辦法在不使用任何導入的情況下以單行方式實現這一目標,即使用基本的列表/字典理解和內置函數。
不,那里沒有。 dict理解會為每個迭代生成一個新項目,並且您的代碼需要生成更少的項目(合並值)。
如果不使用(難看的,非Python的)副作用技巧,就無法訪問早期迭代中生成的密鑰。 將會由理解產生的dict
對象尚不存在,因此也無法產生自引用。
只要堅持您的for
循環,它就會更具可讀性。
另一種選擇是使用排序和分組,O(NlogN)算法與直接循環的簡單O(N):
from itertools import groupby
from operator import itemgetter
res = {key: sum(t[1] for t in group)
for key, group in groupby(sorted(data, key=itemgetter(0)), key=itemgetter(0))}
不要使用oneliner。 而是使用collections.defaultdict
和一個簡單的for循環:
>>> pairs = [('a', 1), ('b', 3), ('a', 4), ('c', 9), ('b', 1), ('d', 3)]
>>> result = defaultdict(int)
>>> for key, value in pairs:
... result[key] += value
...
>>> result
defaultdict(<class 'int'>, {'a': 5, 'c': 9, 'b': 4, 'd': 3})
它易於理解,pythonic且快速。
使用reduce
和collections.Counter
:
>>> from operator import add
>>> from collections import Counter
>>> reduce(add, (Counter(dict([x])) for x in data))
Counter({'c': 9, 'a': 5, 'b': 4, 'd': 3})
這幾乎就像您要嘗試執行的操作。 但是我不建議這樣做,因為可讀性會受到影響。
data = [('a',1),('b',3),('a',4),('c',9),('b',1),('d',3)]
print reduce(lambda d,i: [d.__setitem__(i[0],d.get(i[0],0)+i[1]),d][1], data, {})
輸出量
{'a': 5, 'c': 9, 'b': 4, 'd': 3}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.