使用元组的嵌套列表创建Python defaultdict

时间:2018-11-13 14:56:42

标签: python python-3.x nested-lists defaultdict dictionary-comprehension

这种情况是我有一个二维列表。内部列表的每一项都是元组(键,值对)。该键可能会在列表中重复。我想即时创建一个默认字典,以使字典最终存储密钥以及2-D列表中该密钥的所有值的累加和。

输入代码:

listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]
finalDict = defaultdict(int)
for eachItem in listOfItems:
    for key, val in eachItem:
        finalDict[key] += val
print(finalDict)

这给了我我想要的东西:defaultdict(<class 'int'>, {'a': 7, 'b': 5, 'c': 0, 'd': 5}),但是我正在寻找一种使用理解的更“ Pythonic”方式。所以我尝试了以下方法:

finalDict = defaultdict(int)
finalDict = {key : finalDict[key]+val for eachItem in listOfItems for key, val in eachItem}
print(finalDict)

但是输出是:{'a': 6, 'b': 2, 'c': 0, 'd': 5}我做错了什么?还是在使用理解性时未即时创建和修改字典?

4 个答案:

答案 0 :(得分:5)

是的,理解力无法即时更新。无论如何,此任务可能更适合通过collections.Counter()调用的.update()

>>> from collections import Counter
>>> c = Counter()
>>> for eachItem in listOfItems:
...     c.update(dict(eachItem))
... 
>>> c
Counter({'a': 7, 'b': 5, 'd': 5, 'c': 0})

答案 1 :(得分:2)

无需使用其他模块的简单解决方案:

let sd = new Date();
const startOfWeek = (date) => {
  let diff = date.getDate() - date.getDay() + (date.getDay() === 0 ? -6 : 1);
  return new Date(date.setDate(diff));
}
const startDay = startOfWeek(sd)
console.log(moment(startDay).format('YYYY-MM-D'));

答案 2 :(得分:2)

这是因为您没有在dict内将任何值分配给finalDict。

在理解中,您实际上是在更改finalDict的类型

据我所知,您无法在理解词典中为词典分配值。

这是获取所需字典的一种方法

from functools import reduce

listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]

list_dict = [{key: val} for eachItem in listOfItems for key, val in eachItem]

def sum_dict(x, y):
    return {k: x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y)}
print(reduce(sum_dict, list_dict))

答案 3 :(得分:1)

尝试使用python的内置方法代替自己编写功能:

详细的解决方案

from itertools import chain, groupby
from operator import itemgetter

listOfItems = [[('a', 1), ('b', 3)], [('a', 6)], [('c', 0), ('d', 5), ('b', 2)]]

# just flat the list of lists into 1 list..
flatten_list = chain(*listOfItems)

# get all elements grouped by the key, e.g 'a', 'b' etc..
first = itemgetter(0)
groupedByKey = groupby(sorted(flatten_list, key=first), key=first))

#sum
summed_by_key = ((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupedByKey)

# create a dict
d = dict(summed_by_key)

print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}

〜一线解决方案

from itertools import chain, groupby
from operator import itemgetter

first = itemgetter(0)
d = dict((k, sum(item[1] for item in tups_to_sum)) for k, tups_to_sum in groupby(sorted(chain(*listOfItems), key=first), key=first))

print(d) # {'a': 7, 'b': 5, 'c': 0, 'd': 5}