2015-07-21 34 views
2

这是我的列表元组对象。它包括重复和相同的密钥是a如何合并具有列表元组对象的键值

a = [("a",1), ("b",3), ("a",5)] 

dict_a = dict(a) 

print dict_a 
# {'a': 5, 'b': 3} 

但我希望我可以得到:

# {'a': 6, 'b': 3} 

如果我不使用forwhile来解决,我可以使用内置的功能呢?

回答

2

我想不出一个基本的解决方案,会比一个简单的循环更好。这将是一个糟糕的解决方案:

from itertools import chain 
from collections import Counter 

a = [("a",1), ("b",3), ("a",5)] 

dict_a = dict(Counter(chain.from_iterable(map(lambda a: a[0] * a[1], a)))) 

print dict_a 
# {'a': 5, 'b': 3} 

这可以变得更糟,并进一步简化联接:

dict_a = dict(Counter("".join(map(lambda a: a[0] * a[1], a)))) 

而且进一步简化应该列出压缩不破for规则:

dict_a = dict(Counter("".join(b[0] * b[1] for n in a)))) 

如果我们导入乘法运算符,缩短(排序)。

from operator import mul 
dict_a = dict(Counter("".join(mul(*b) for b in a))) 

另一种可怕的想法是删除Count和使用次数,但requies我们使用一个变量。

b = "".join(mul(*b) for b in a) 
dict_a = {e[0]: b.count(e) for e in b} 

虽然我们可能只是遍历a成一个字典,计数,因为我们走:

from operator import itemgetter 
dict_a = {e[0]: sum(map(itemgetter(1), filter(lambda a: a[0] == e[0], a))) for e in a} 
1
def dict_sum(a, totals=defaultdict(int)): 
    k, v = a.pop() 
    totals[k] += v 
    return totals if not a else dict_sum(a, totals) 
a = [("a",1), ("b",3), ("a",5)] 
res = dict_sum(a) 
print res 

输出:

defaultdict(<type 'int'>, {'a': 6, 'b': 3}) 
2

个人而言,我会去这样的解决方案:

import collections 

dict_a = collections.defaultdict(int) 
for k, v in a: 
    dict_a[k] += v 

但是,如果你”真的很想这样做,这里是一个没有for/while循环的解决方案:)

import collections 

dict_a = collections.Counter(sum(map(lambda (x, y): (x,) * y, a),())) 
+0

这是一个很好的答案,但笔者没有提到他不想使用for或while循环。 – matthewatabet

+2

@matthewatabet:我知道,但我仍然建议这:)其他解决方案实际上都使用循环,他们只是更好地隐藏它;) – Wolph

+0

是的,你是绝对正确的:)这是一个有趣的精神位试图不直接使用循环的体操...但实际上这个答案是最容易阅读的。 – matthewatabet

2

你可以使用内置的map()功能和部分:

from functools import partial 


def accum(memo, key_value): 
    key, value = key_value 
    memo[key] = value + memo.get(key, 0) 
    return key, memo[key] 

a = [("a", 1), ("b", 3), ("a", 5)] 

dict_a = dict(map(partial(accum, {}), a)) 

print dict_a 
>>> {'a': 6, 'b': 3} 
+1

这绝对是一个创意选项,从我+1:P – Wolph

相关问题