Way 2 does not work because the keys do not exists yet. You can not use +=
for values on non existent keys - only on keys that contain (f.e.) integers.
Collection of alternate ways:
O(n**2)
- solution:
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}
Worst because: list.count()
iterates the whole list to count one elements occurences. It touches this list 6 times for every number in it. It counts 2
four times (just to make sure) and reassignes the counted value to the key of over and over.
It is a O(n**2) approach. You can "optimize" it by only looping over the set(list1)
which reduces it to counting only each unique number (3*6 instead of 6*6) - but the problem has several O(n) solution == one pass over the list.
Your solution is O(2*n) - iterating the list twice to create zero-indexes and then count them.
O(n)
- solutions (that differ in performance):
# 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)))
Output's:
{'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:
with Counter and defaultdict being the fastisht methods - you would have to measure to get a "winner".