Best way to define multidimensional dictionaries in python?

50,455

Solution 1

Tuples are hashable. Probably I'm missing the point, but why don't you use a standard dictionary with the convention that the keys will be triples? For example:

userdict = {}
userdict[('site1', 'board1', 'username')] = 'tommy'

Solution 2

You can create a multidimensional dictionary of any type like this:

from collections import defaultdict
from collections import Counter

def multi_dimensions(n, type):
  """ Creates an n-dimension dictionary where the n-th dimension is of type 'type'
  """  
  if n<=1:
    return type()
  return defaultdict(lambda:multi_dimensions(n-1, type))

>>> m = multi_dimensions(5, Counter)
>>> m['d1']['d2']['d3']['d4']
Counter()

Solution 3

This is a pretty subjective question from my perspective. For me, the real question would be at what point do you promote this nested data structure to objects with methods to insulate you from changes. However, I've been known to create large prototyping namespaces with the following:

from collections import defaultdict

def nesteddict(): 
  return defaultdict(nesteddict)

Solution 4

This is highly subjective - but if your dict is getting to be more than 2-n deep, I would revert to creating a class and defining methods/properties to do what you want.

I think your end goal would be to create a "multi-column" data structure so you can store any number of attributes for a particular object (in this case, a site). Creating a site class would accomplish that and then you can stick instances wherever you would any other object (variable) - with some noted exceptions.

Share:
50,455
James
Author by

James

Updated on February 01, 2020

Comments

  • James
    James over 4 years

    I'm currently using the method below to define a multidimensional dictionary in python. My question is: Is this the preferred way of defining multidimensional dicts?

    from collections import defaultdict
    
    def site_struct(): 
        return defaultdict(board_struct)
    
    def board_struct(): 
        return defaultdict(user_struct)
    
    def user_struct(): 
        return dict(pageviews=0,username='',comments=0)
    
    userdict = defaultdict(site_struct)
    

    to get the following structure:

    userdict['site1']['board1']['username'] = 'tommy'
    

    I'm also using this to increment counters on the fly for a user without having to check if a key exists or is set to 0 already. E.g.:

    userdict['site1']['board1']['username']['pageviews'] += 1