Rebuild list of objects with redundancies on objects' attribute

Peter Otten __peter__ at web.de
Thu Jan 10 12:29:01 CET 2008


Nico Grubert wrote:

> Hi there
> 
> I have a list of dummy objects which have the attributes 'location', 
> 'name', 'gender'.
> Now I want to rebuild this list in order to avoid redundancies on 
> objects with the same 'location'.
> 
> Example:
> 
> #------------------------------------------------------------------
> class Dummy:
>      pass
> 
> a = Dummy()
> a.location = 'tokio'
> a.name = 'john'
> a.gender = 'm'
> 
> b = Dummy()
> b.location = 'tokio'
> b.name = 'peter'
> b.gender = 'm'
> 
> c = Dummy()
> c.location = 'madrid'
> c.name = 'susan'
> c.gender = 'f'
> 
> d = Dummy()
> d.location = 'london'
> d.name = 'alex'
> d.gender = 'm'
> 
> persons = [a, b, c, d]
> 
> print "loc     name   gender"
> print "---------------------"
> for obj in persons:
>      print "%s - %s - %s" % (obj.location, obj.name, obj.gender)
> 
> #------------------------------------------------------------------
> 
> The output reads like this:
> 
>    loc     name   gender
>    ---------------------
>    tokio   john   m
>    tokio   peter  m
>    madrid  susan  f
>    london  alex   m
> 
> I want to create this list (where name and gender are lists):
>    loc      name          gender
>    -----------------------------
>    tokio    [john, peter] [m]
>    madrid   [susan]       [f]
>    london   [alex]        [m]
> 
> How can I do this?

Put the persons into a dictionary using the location as key

from collections import defaultdict
groups = defaultdict(list)
for p in persons:
    groups[p.location].append(p)

Below is a spoiler that uses itertools.groupby(), but you learn more if you
try to work it out yourself ;)



from itertools import groupby

def location(p):
    return p.location

persons.sort(key=location)
print "loc     name   gender"
print "---------------------"
for loc, group in groupby(persons, key=location):
    group = list(group)
    genders = sorted(set(p.gender for p in group))
    names = sorted(p.name for p in group)
    print "%s - %s - %s" % (loc, names, genders)

Peter



More information about the Python-list mailing list