Reputation: 645
I'm learning some list/dict comprehension and I'm stuck!!!
I really don't understand the following...
I have this program:
def histogram_for(word):
adict = dict()
for c in word:
adict[c] = adict.get(c, 0) + 1
print adict
return adict
def histogram_dc(word):
adict = dict()
adict = {c: (adict.get(c, 0) + 1) for c in word}
print adict
return adict
def histogram_lc(word):
adict = dict()
adict = dict([(c, (adict.get(c, 0) + 1)) for c in word])
print adict
return adict
word = "Football"
histogram_for(word.lower())
histogram_dc(word.lower())
histogram_lc(word.lower())
And i get these results:
{'a': 1, 'b': 1, 'f': 1, 'l': 2, 'o': 2, 't': 1}
{'a': 1, 'b': 1, 'f': 1, 'l': 1, 'o': 1, 't': 1}
{'a': 1, 'b': 1, 'f': 1, 'l': 1, 'o': 1, 't': 1}
Why the only working one is the "for" method?
Upvotes: 2
Views: 174
Reputation: 159865
Quite simply because while the processing is happening in _dc
and _lc
adict
is empty, while in _for
it's being updated on each turn of the for
loop. A comprehension can be de-sugared into a for
loop of its own:
adict = dict()
adict = {c: (adict.get(c, 0) + 1) for c in word}
becomes:
adict = dict()
# Handwaving for what Python actually does
$newdict = {}
for c in word:
$newdict[c] = adict.get(c, 0) + 1
adict = $newdict
Use collections.Counter
(or the for-loop version) if you need to keep track of a set of keys and counts of occurrences.
Upvotes: 3
Reputation: 1799
As Sean Vieira said, the class collections.Counter
and its method most_common
are the best solution to your need.
But, if you really want to keep list/dict comprehension, I suggest using set
and count
:
def histogram_dc(word):
adict = dict()
adict = {c: word.count(c) for c in set(word)}
print adict
return adict
def histogram_lc(word):
adict = dict()
adict = dict([(c, word.count(c)) for c in set(word)])
print adict
return adict
Upvotes: 1