Counter is definitely the way to go (and I've upvoted Jaime's answer).
If you want to do it yourself and iterate only once, this should work :
d={}
for l in s:
d[l] = d.get(l,0) + 1
There might be a short/more pythonic way to do so but it works...
Edit :
I must confess that Jaime's comment to this answer surprised me but I've just tested this code :
from profilehooks import profile
s="qwertyuiopasdfghjklzxcvbnm"
@profile
def function1(s):
d={}
for l in s:
d[l] = d.get(l,0)+1
return d
@profile
def function2(s):
return dict((char_, s.count(char_)) for char_ in set(s))
for i in xrange(0,200):
function1(s*i)
function2(s*i)
And the results can hardly be contested :
*** PROFILER RESULTS ***
function2 (./fsdhfsdhjk.py:13)
function called 200 times
10948 function calls in 0.161 seconds
Ordered by: cumulative time, internal time, call count
ncalls tottime percall cumtime percall filename:lineno(function)
200 0.083 0.000 0.161 0.001 fsdhfsdhjk.py:13(function2)
5374 0.033 0.000 0.077 0.000 fsdhfsdhjk.py:15(<genexpr>)
5174 0.044 0.000 0.044 0.000 {method 'count' of 'str' objects}
200 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
0 0.000 0.000 profile:0(profiler)
*** PROFILER RESULTS ***
function1 (./fsdhfsdhjk.py:6)
function called 200 times
517800 function calls in 2.891 seconds
Ordered by: cumulative time, internal time, call count
ncalls tottime percall cumtime percall filename:lineno(function)
200 1.711 0.009 2.891 0.014 fsdhfsdhjk.py:6(function1)
517400 1.179 0.000 1.179 0.000 {method 'get' of 'dict' objects}
200 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
0 0.000 0.000 profile:0(profiler)
TL;DR
Jaime's solution (function2
) is 18 times faster than mine (function1
).