使用列表中出现的项目数创建字典会产生KeyError

时间:2019-01-15 18:49:09

标签: 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 in list2:
  dict2[keys]+=1
print('dict2 is',dict2)

1 个答案:

答案 0 :(得分:2)

方法2不起作用,因为键尚不存在。不能将+=用于不存在的键上的值-只能用于包含(例如)整数的键上。


其他方法的集合:

O(n**2)-解决方案:

list1=['1','2','2','3','2','2']

# the worst petrformance I can imagine:
worst = {}
for item in list1:
    worst[item] = list1.count(item)

print(worst) # {'1': 1, '3': 1, '2': 4} 

最糟糕的原因是: list.count()迭代整个列表以计算一个元素的出现。对于列表中的每个数字,它都会触摸6次。它会2进行四次计数(只是为了确保),然后将计数值重新分配给over和over键。

这是一种O(n ** 2)方法。您可以通过仅遍历set(list1)来“优化”它,从而将其减少为仅对每个唯一数字(3 * 6而不是6 * 6)进行计数-但是问题有多个O(n)解决方案==一遍在列表上。

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

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

# zeroth'st way: check and test and create if needed else add
ddd = {}
for item in list1:   # touches each item exactly once
    if item in ddd:       # but uses additional checks and conditions 
        ddd[item] += 1
    else:
        ddd[item] = 1

print(ddd) 

#second way   # slowish - but better then two for loops (kinda your one way optimized)
dict2={}
for key in list1:             # touches each element once, no checks but
    dict2.setdefault(key,0)   # setdefault + assignment is slower then defaultdict
    dict2[key]+=1

print('dict2 is',dict2)

# third way     # faster then setdefault due to  optimizations in defaultdict
from collections import defaultdict

d = defaultdict(int)
for key in list1:
    d[key]+=1

print("defaultdict is", d)

# 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}    

Doku:

Counter和defaultdict是最快的方法-您必须衡量以获得“优胜者”。