Python 创建一个包含列表中项目出现次数的dict会导致KeyError

Python 创建一个包含列表中项目出现次数的dict会导致KeyError,python,dictionary,counting,Python,Dictionary,Counting,我尝试将列表中的值放入字典,并计算它们在该列表中出现的次数,但是第二种方法不起作用。有人知道原因吗 #one way list1=['1','2','2','3','2','2'] dict1={} for keys in list1: dict1[keys]=0 for keys in list1: dict1[keys]=dict1[keys]+1 print('dict1 is',dict1) #second way list2=list1 dict2={} for keys i

我尝试将列表中的值放入字典,并计算它们在该列表中出现的次数,但是第二种方法不起作用。有人知道原因吗

#one way
list1=['1','2','2','3','2','2']
dict1={}
for keys in list1:
  dict1[keys]=0
for keys in list1:
  dict1[keys]=dict1[keys]+1
print('dict1 is',dict1)

#second way
list2=list1
dict2={}
for keys in list2:
  dict2[keys]+=1
print('dict2 is',dict2)

方法2不起作用,因为密钥还不存在。不能对不存在的键上的值使用
+=
,只能对包含(f.e.)整数的键使用


备选方法的集合:

{'1': 1, '3': 1, '2': 4} 
dict2 is {'1': 1, '2': 4, '3': 1}
defaultdict is defaultdict(<class 'int'>, {'1': 1, '2': 4, '3': 1})
groupby is {'1': 1, '2': 4, '3': 1}
Counter({'2': 4, '1': 1, '3': 1})
{'1': 1, '3': 1, '2': 4}    
O(n**2)
-解决方案:

{'1': 1, '3': 1, '2': 4} 
dict2 is {'1': 1, '2': 4, '3': 1}
defaultdict is defaultdict(<class 'int'>, {'1': 1, '2': 4, '3': 1})
groupby is {'1': 1, '2': 4, '3': 1}
Counter({'2': 4, '1': 1, '3': 1})
{'1': 1, '3': 1, '2': 4}    
最糟糕的原因是:
list.count()
迭代整个列表以计算一个元素的出现次数。对于列表中的每个数字,它都会触及该列表6次。它计数
2
四次(只是为了确保),并将计数值重新分配给over and over键

这是一种O(n**2)方法。您可以通过只在
集合(list1)
上循环来“优化”它,从而将它减少为只计算每个唯一的数字(3*6而不是6*6)-但是问题有几个O(n)解决方案==一次通过列表

您的解决方案是O(2*n)-迭代列表两次以创建零索引,然后对它们进行计数

O(n)
-解决方案
(性能不同)

{'1': 1, '3': 1, '2': 4} 
dict2 is {'1': 1, '2': 4, '3': 1}
defaultdict is defaultdict(<class 'int'>, {'1': 1, '2': 4, '3': 1})
groupby is {'1': 1, '2': 4, '3': 1}
Counter({'2': 4, '1': 1, '3': 1})
{'1': 1, '3': 1, '2': 4}    




输出:

{'1': 1, '3': 1, '2': 4} 
dict2 is {'1': 1, '2': 4, '3': 1}
defaultdict is defaultdict(<class 'int'>, {'1': 1, '2': 4, '3': 1})
groupby is {'1': 1, '2': 4, '3': 1}
Counter({'2': 4, '1': 1, '3': 1})
{'1': 1, '3': 1, '2': 4}    
{'1':1,'3':1,'2':4}
dict2是{'1':1,'2':4,'3':1}
defaultdict是defaultdict(,{'1':1,'2':4,'3':1})
groupby是{'1':1,'2':4,'3':1}
计数器({'2':4,'1':1,'3':1})
{'1': 1, '3': 1, '2': 4}    

Doku:


由于Counter和defaultdict是fastisht方法,您必须进行测量才能获得“赢家”。

list2=list1
是初学者常见的错误-它只是相同数据的另一个名称-请参阅。。。它是一个对你的代码没有任何作用的空函数,是的,你是对的。实际上,我只想用两种方式来说明列表的值。然而,第二种方法有一个错误,但我不知道如何修复它,第一种方法可以得到dict,比如{'1':1,'2':4,'3':1},但是我认为代码太复杂了,可能与在
集合
模块中为这个任务专门构建的类重复:<代码>计数器(列表1)是
计数器({'2':4,'1':1,'3':1})
,可以被视为一个dict。看起来最惯用的(如果不是最有效的)是
集合。计数器(列表1)
# fourth way     # slower because it needs additional list sorting to work
from itertools import groupby

dd = { k:len(list(v)) for k,v in groupby(sorted(list1))} #needs sorted list here

print("groupby is", dd)
# fifth way using Counter
from collections import Counter 

print(     Counter(list1))   
print(dict(Counter(list1)))  
{'1': 1, '3': 1, '2': 4} 
dict2 is {'1': 1, '2': 4, '3': 1}
defaultdict is defaultdict(<class 'int'>, {'1': 1, '2': 4, '3': 1})
groupby is {'1': 1, '2': 4, '3': 1}
Counter({'2': 4, '1': 1, '3': 1})
{'1': 1, '3': 1, '2': 4}