使用字典理解

时间:2015-09-16 19:30:15

标签: python dictionary nested-lists dictionary-comprehension

所以我将数据结构化为嵌套列表,如此

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]

我试图将其转换为看起来像这样的输出

{'A': 1, 'C': -1, 'B': 7}

基本上总结所有的A,B和C,将输出作为字典。

我写了这段代码,给出了正确的答案

playerSum = {}
for ele in data:
    if ele[0] not in playerSum:
        playerSum[ele[0]] = int(ele[1])
    else:
        playerSum[ele[0]] += int(ele[1])

但是,我试图将上面的代码块转换为字典理解。我主要理解如何去做,但我不明白如何写+ =作为词典理解。任何关于结构的指导都会很棒。

到目前为止,我有这个

playerSum = {ele[0]: int(ele[1]) if ele[0] not in playerSum else playerSum[ele[0]] += int(ele[1]) for ele in data}

编辑:所以@achampion能够解决它。谢谢!

{key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)}

4 个答案:

答案 0 :(得分:2)

理解这样做是不切实际的 就像练习一样,你可以使用协程为你做计数,但你有效地创建了两次字典:

from collections import defaultdict
def count():
    cache = defaultdict(int)
    k, v = yield
    while True:
        cache[k] += v
        k, v = yield cache[k]

counter = count()  # Create coroutine
next(counter)      # Prime coroutine

data = [['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'],
        ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]

{k: counter.send((k, int(v))) for k, v in data}  # Meets the challenge :)

结果:

{'A': 1, 'B': 7, 'C': -1}

或者是一个真正丑陋的单行,不需要协程并且不是二次方(不是理解):

>>> reduce(lambda d, (k,v): d.__setitem__(k, d.get(k,0)+int(v)) or d, data, {})  # Py2.7
{'A': 1, 'B': 7, 'C': -1}

最后一个基于@Prune的非常低效但真实的词典理解:

>>> {key: sum(int(v) for k, v in data if k==key) for key in set(k for k, _ in data)}
{'A': 1, 'B': 7, 'C': -1}

答案 1 :(得分:0)

最好的方式是最明显的方式

from collections import defaultdict
playerSum = defaultdict(int)

for key, value in data:
   playerSum[key] += int(value)

答案 2 :(得分:0)

可能使用dict理解,因为你的值会被覆盖,dict在理解完成之前不会被创建,所以即使你可以没有+ =。 除非你有playerSum = {}某处,否则你的代码会因为NameError而出错,如果你这样做,你只需将名称重新绑定到你的dict comp的结果,这样playerSum = {}基本上什么都不做。

实现目标的唯一方法就是按照自己的解决方案。为了更有效的方法您可以解压缩子列表并将第二个元素转换为int,使用collections.defaultdict对值进行求和:

from collections import defaultdict

d = defaultdict(int)

for a,b  in data:
    d[a] += int(b)

print(d)
defaultdict(<type 'int'>, {'A': 1, 'C': -1, 'B': 7})

或使用常规字典:

d = {}

for a, b in data:
    d[a] = d.get(a,0) + int(b)

print(d)
{'A': 1, 'C': -1, 'B': 7}

答案 3 :(得分:0)

正如你所问,我是在一次理解中完成的。

dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key)) for key in [id for id in set([elem[0] for elem in data])] ])

从外到内:

  • 构建列表中使用的一组ID。

  • 对于每个ID,请列出相关值。

  • 总结清单。

  • 将ID和总和作为一对发出(收益)。

  • 将此元组列表转换为字典。

测试:

data = [['A', '1'], ['B', '2'], ['C', '3'],
        ['A', '-2'], ['B', '4'], ['C', '1'],
        ['A', '2'], ['B', '1'], ['C', '-5']]
playerSum = dict ([(key, sum(int(elem[1]) for elem in data if elem[0]==key))
                   for key in [id for id in set([elem[0] for elem in data])] ])
print data
print playerSum

结果:

[['A', '1'], ['B', '2'], ['C', '3'], ['A', '-2'], ['B', '4'], ['C', '1'], ['A', '2'], ['B', '1'], ['C', '-5']]
{'A': 1, 'C': -1, 'B': 7}