Search code examples
pythondictionarycounterdefaultdict

Nested dictionary with defaults


Is there a way to make a nested dictionary such that I can say mydict[x][y][z] += 1, where mydict[x][y][z] did not previously exist, and defaults to 0 (and would be 1 after incrementing)?

I looked into answers to a similar question in which you can say mydict[x][y][z] = 1 using defaultdict from the collections class (Declaring a multi dimensional dictionary in python), but this does not allow you to assume a default value and then increment.


Solution

  • Yes, you can do this with the collections module:

    from collections import defaultdict, Counter
    
    d = defaultdict(lambda: defaultdict(lambda: Counter()))
    
    d['A']['B']['C'] += 1
    
    # defaultdict(<function __main__.<lambda>>,
    #             {'A': defaultdict(<function __main__.<lambda>.<locals>.<lambda>>,
    #                          {'B': Counter({'C': 1})})})
    

    Note this is also possible via only using nested defaultdict:

    d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
    

    However, given Counter was created for the specific purpose of incrementing integers, this would be the method I prefer.