I use setdefault to count instances like this (this is the stripdown version):
user_to_count_map = {}
for username in list_of_usernames:
x = user_to_count_map.setdefault(username, 0)
x += 1
user_to_count_map[username] = x + 1
for username in sorted(usernmae_to_count_map):
print username, user_to_count_map[username]
I don't like the assigning back to the map, because the real code is more complex with multiple count increas. But I do seem to need to do that. Is there an easy way around that?
You could make the counter a list with one element, effectively making it a mutable:
user_to_count_map = {}
for username in list_of_usernames:
x = user_to_count_map.setdefault(username, [0])
x[0] += 1
for username, counter in sorted(user_to_count_map.items()):
print username, counter[0]
I am not sure if that makes your code any more readable, as explicit is better than implicit.
Or if use python 2.7 or newer (or use a convenient backport), you could use a Counter
object:
from collections import Counter
user_to_count_map = Counter()
for username in list_of_usernames:
user_to_count_map[username] += 1
for username, counter in sorted(user_to_count_map.items()):
print username, counter[0]
Note that by using a Counter
you have a dictionary that automatically gives you a default value of 0. It otherwise acts like a dictionary holding integer values, so you can increment and decrement these values any way you like (including adding more than 1).
The same effect can be had with defaultdict
, also in the collections module, but note that the Counter
class offers functionality. defaultdict
is present in python 2.5 and up; example:
from collections import defaultdict
user_to_count_map = defaultdict(lambda: 0)
for username in list_of_usernames:
user_to_count_map[username] += 1
Alternatively, you could just dispense with the setdefault altogether, as you are always assigning back to the mapping anyway:
user_to_count_map = {}
for username in list_of_usernames:
x = user_to_count_map.get(username, 0)
x += 1
user_to_count_map[x] = x
for username, counter in sorted(user_to_count_map.items()):
print username, counter[0]