Search code examples
pythoncompound-assignment

Better way to write 'assign A or if not possible - B'


So, in my code I have a dictionary I use to count up items I have no prior knowledge of:

if a_thing not in my_dict:
    my_dict[a_thing] = 0
else:
    my_dict[a_thing] += 1

Obviously, I can't increment an entry of a value that doesn't exist yet. For some reason I have a feeling (in my still-Python-inexperienced brain) there might exist a more Pythonic way to do this with, say, some construct which allows to assign a result of an expression to a thing and if not possible something else in a single statement.

So, does anything like that exist in Python?


Solution

  • This looks like a good job for defaultdict, from collections. Observe the example below:

    >>> from collections import defaultdict
    >>> d = defaultdict(int)
    >>> d['a'] += 1
    >>> d
    defaultdict(<class 'int'>, {'a': 1})
    >>> d['b'] += 1
    >>> d['a'] += 1
    >>> d
    defaultdict(<class 'int'>, {'b': 1, 'a': 2})
    

    defaultdict will take a single parameter which indicates your initial value. In this case you are incrementing integer values, so you want int.

    Alternatively, since you are counting items, you could also (as mentioned in comments) use Counter which will ultimately do all the work for you:

    >>> d = Counter(['a', 'b', 'a', 'c', 'a', 'b', 'c'])
    >>> d
    Counter({'a': 3, 'c': 2, 'b': 2})
    

    It also comes with some nice bonuses. Like most_common:

    >>> d.most_common()
    [('a', 3), ('c', 2), ('b', 2)]
    

    Now you have an order to give you the most common counts.