我尝试将列表中的值放入字典中,并计算它们在该列表中出现的次数,但是第二种方法不起作用。有人知道原因吗?
#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)
答案 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是最快的方法-您必须衡量以获得“优胜者”。