根据两个列表中元组的出现更新defaultdict计数

时间:2018-11-16 21:49:45

标签: python list dictionary tuples counter

我有两个列表,想创建一个字典来记录元组的出现。

我当前的代码:

tup_to_find_test = [('good', 'pea'), ('leaf', 'sweet')] 
self_per_list_test = [('leaf', 'liquid'), ('leaf', 'sweet'), ('leaf', 'sweet'),('good', 'pea'),('good', 'pea'),('good', 'pea')]
from collections import defaultdict
tup_dict_test = defaultdict(int)
for tup_to_find_test in self_per_list_test:
   tup_dict_test[tup_to_find_test]+=1

我的结果是:

defaultdict(int, {('leaf', 'liquid'): 1, ('leaf', 'sweet'): 1, ('good', 'pea'): 3})

我想要的结果是:

('leaf', 'liquid'): 0, ('leaf', 'sweet'): 2, ('good', 'pea'): 3})

我不知道为什么('leaf', 'liquid')的计数为1。defaultdict(int)的默认整数不是零吗?为什么我的('leaf', 'liquid')元组有1个?

3 个答案:

答案 0 :(得分:2)

这行没有按照您的想法做:

for tup_to_find_test in self_per_list_test:
   # ...

在这里,您逐个元素地列出列表,在这种情况下为self_per_list_test的元素。没有没有过滤。当您的for循环迭代时,tup_to_find_test依次代表('leaf', 'liquid')('leaf', 'sweet')等。事实上,该名称与您先前定义的变量相同,这只会混淆

相反,您可以使用三元语句来区分操作:

for item in self_per_list_test:
    tup_dict_test[item] += 1 if item in tup_to_find_test else 0

print(tup_dict_test)

defaultdict(int, {('leaf', 'liquid'): 0, ('leaf', 'sweet'): 2, ('good', 'pea'): 3})

collections.Counter在Python中更为惯用。在字典理解中使用set进行O(1)查找是一个好习惯。

from collections import Counter

tup_to_find_set = set(tup_to_find_test)
counts = Counter(self_per_list_test)

tup_dict_test = {k: v if k in tup_to_find_set else 0 for k, v in counts.items()}

print(tup_dict_test)

{('leaf', 'liquid'): 0, ('leaf', 'sweet'): 2, ('good', 'pea'): 3}

答案 1 :(得分:1)

  

defaultdict(int)的默认整数不是零吗?

是的

  

为什么我的('leaf','liquid')元组有1个?

您写道:

tup_dict_test[tup_to_find_test]+=1

也就是说,找到当前值(这将创建一个新的零集),然后将其添加一个并将结果存储回去。结果值为1。

答案 2 :(得分:1)

无需重新设计轮子。您可以为此使用出色的counter标准模块库中的collections

from collections import Counter

tup_to_find_test = [('good', 'pea'), ('leaf', 'sweet')] 
self_per_list_test = [('leaf', 'liquid'), ('leaf', 'sweet'), ('leaf', 'sweet'),('good', 'pea'),('good', 'pea'),('good', 'pea')]

c = Counter(self_per_list_test)

for key in c:
    if key not in tup_to_find_test:
        c[key] = 0

print(c)

>>Counter({('good', 'pea'): 3, ('leaf', 'sweet'): 2, ('leaf', 'liquid'): 0})

在这里,我们基于self_per_list_test创建一个计数器,如果在tup_to_find_test中找不到计数,则将计数更新为零。希望这是解决问题的一种更直观的方法。