Python 根据两个列表中元组的出现情况更新defaultdict计数
我有两个列表,想创建一个字典来记录元组的出现 我当前的代码:Python 根据两个列表中元组的出现情况更新defaultdict计数,python,list,dictionary,tuples,counter,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 defaultdic
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})
我期望的结果是:
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)
0的默认整数不是零吗?为什么我在('leaf','liquid')
元组中得到了1
defaultdict(int)
0的默认整数不是零吗
对
为什么我的('leaf','liquid')元组得到1
你写道:
tup_dict_test[tup_to_find_test]+=1
也就是说,找到当前值,该值将创建一个设置为零的新值,然后向其中添加一个值,并将结果存储回去。结果值为1。这一行没有执行您认为的操作:
for tup_to_find_test in self_per_list_test:
# ...
在这里,您正在对列表元素进行迭代,在本例中,self\u per\u list\u test
的元素。没有进行过滤。当您的for
循环迭代时,tup\u to\u find\u 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})
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}
没有重新发明轮子。您可以使用奇妙的
集合
标准模块库中的计数器
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\u per\u list\u test
创建一个计数器,如果在tup\u to\u find\u test
中找不到,则将计数更新为零。希望这是一种更直观的方法来解决您的问题。您有一次('leaf','liquid')
在self\u per\u list\u test
。与defaultdict
相比,计数器
是否比使用defaultdict
更快?嗯,您无法将defaultdict
与计数器
进行比较,defaultdict
调用工厂函数以提供缺少的值。计数器
经过优化,可计算散列值。在这个用例中,如果您的目的只是计数,我将使用计数器
。我在我的数据集上尝试了这两种方法。你是对的。因为我的目标是简单地计算元组的频率,所以我应该选择Counter
。感谢您的智能/直截了当的解决方案!(我想我对我的问题想得太多了)是的,希望能有帮助。如果您发现这里的任何答案都很有用,请接受帮助您解决问题的最佳答案。这是@BernardL solution的单线形式,对吗?它非常整洁和聪明!谢谢@艾比,是的,如果你想坚持使用defaultdict
,它确实是一行。建议通过set
使用哈希来提高效率。