这是我的list-tuple对象。它包括重复和相同的键a
。
a = [("a",1), ("b",3), ("a",5)]
dict_a = dict(a)
print dict_a
# {'a': 5, 'b': 3}
但我希望我能得到:
# {'a': 6, 'b': 3}
如果我不使用for
或while
来解决,我可以使用内置函数吗?
答案 0 :(得分: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
并使用count,但它要求我们使用变量。
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 :(得分: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), ()))
答案 2 :(得分: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}
答案 3 :(得分: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})