使用列表中项目的出现次数创建字典会给出 KeyError
Creating a dict with numbers of occurrences of items in a list gives KeyError
我尝试将列表中的值放入字典,并计算它们在该列表中出现的次数,但是第二种方法不起作用。有谁知道原因吗?
#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.) 整数的键上使用。
备选方式合集:
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) 的方法。您可以 "optimize" 它仅通过遍历 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}
独库:
Counter 和 defaultdict 是 fastisht 方法 - 您必须测量才能获得 "winner"。
我尝试将列表中的值放入字典,并计算它们在该列表中出现的次数,但是第二种方法不起作用。有谁知道原因吗?
#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.) 整数的键上使用。
备选方式合集:
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) 的方法。您可以 "optimize" 它仅通过遍历 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}
独库:
Counter 和 defaultdict 是 fastisht 方法 - 您必须测量才能获得 "winner"。