Search code examples
pythondictionarynestedcatalog

catalogue a list of dictionaries


I have a list of dictionaries:

people = [{"name": "Roger", "city": "NY", "age": 20, "sex": "M"},
          {"name": "Dan", "city": "Boston", "age": 20, "sex": "M"},
          {"name": "Roger", "city": "Boston", "age": 21, "sex": "M"},
          {"name": "Dana", "city": "Dallas", "age": 30, "sex": "F"}]

I want to catalogue them, for example I choose these keys:

field = ("sex", "age")

I need a function catalogue(field, people) that give me:

{ "M": 
      { 20: [{"name": "Roger", "city": "NY", "age": 20, "sex": "M"},
             {"name": "Dan", "city": "Boston", "age": 20, "sex": "M"}],
        21: [{"name": "Roger", "city": "Boston", "age": 21, "sex": "M"}]
      },
 { "F":
      { 30: [{"name": "Dana", "city": "Dallas", "age": 30, "sex": "F"}] }
 }

when len(field)==1 it's simple. I want to do something like this:

c = catalogue(field, people)
for (sex, sex_value) in c.iteritems():
   for (age, age_value) in sex_value.iteritems():
       print sex, age, age_value["name"]

Solution

  • recursively:

    import itertools, operator
    
    def catalog(fields,people):
        cur_field = operator.itemgetter(fields[0])
        groups = itertools.groupby(sorted(people, key=cur_field),cur_field)
        if len(fields)==1:
            return dict((k,list(v)) for k,v in groups)
        else:
            return dict((k,catalog(fields[1:],v)) for k,v in groups)
    

    test:

    import pprint
    pprint.pprint(catalog(('sex','age'), people))
    {'F': {30: [{'age': 30, 'city': 'Dallas', 'name': 'Dana', 'sex': 'F'}]},
     'M': {20: [{'age': 20, 'city': 'NY', 'name': 'Roger', 'sex': 'M'},
                {'age': 20, 'city': 'Boston', 'name': 'Dan', 'sex': 'M'}],
           21: [{'age': 21, 'city': 'Boston', 'name': 'Roger', 'sex': 'M'}]}}