[Tutor] looping through and comparing lists of dictionaries

Don Arnold Don Arnold" <darnold02@sprynet.com
Wed Apr 23 07:01:40 2003

----- Original Message -----
From: "bkd" <bkd@graphnet.com>
To: <tutor@python.org>
Sent: Wednesday, April 23, 2003 2:04 AM
Subject: [Tutor] looping through and comparing lists of dictionaries

> I have two lists of dictionaries. One is freshly downloaded from a telnet
> screenscrape, the other is read from a file that's a snapshot of the last
> screenscrape:
> olddata=[{'name':'Betty','hair':'Blonde','role':'Student'},
> {'name':'Veronica','hair':'Brunette','role':'Student'},
> {'name':'Maryann','hair':'Brunette','role':'Castaway'},
> {'name':'Ginger','hair':'Redhead','role':'Castaway'},
> {'name':'Jeanne','hair':'Blond','role':'Genie'},
> {'name':'Serena','hair':'Brunette','role':'Genie'},
> {'name':'Samantha','hair':'Blond','role':'Witch'}]
> newdata=[{'name':'Betty','hair':'Redhead','role':'Student'},
> {'name':'Veronica','hair':'Redhead','role':'Student'},
> {'name':'Maryann','hair':'Brunette','role':'Castaway'},
> {'name':'Ginger','hair':'Redhead','role':'Castaway'},
> {'name':'Jeanne','hair':'Blond','role':'Genie'},
> {'name':'Serena','hair':'Brunette','role':'Genie'},
> {'name':'Samantha','hair':'Redhead','role':'Witch'}]
> I want to find all the girls who have dyed their hair red since the last
> time I checked. I start by running a loop that pulls all the names of all
> the Redheads into a list:
> redheads=[]
> for girl in range(len(newdata)):
>     if newdata[girl]['hair']=='Redhead':
> redheads.append(newdata[girl]['name'])
> this gives me:
> ['Betty','Veronica','Ginger','Samantha']
> for redheads.
> Now, I need to check olddata to see if any of these girls were redheads,
> eliminate them from the list.
> What I have now is this:
> for girl in range(len(redheads)):
>     if len(redheads)==0: break
>     else:
>         for line in range(len(olddata)):
>             if len(redheads)==0: break
>             elif olddata[line]['name']<>redheads[girl]: pass
>             elif olddata[line]['hair']=='Redhead': del redheads[girl]
> But this breaks with an 'index out of range' error. The lesson being, do
> mess with the list you're indexing over, make a copy and mess with the
> But still, I can't help but think there must be a better way to do this.
> suggestions where I should look first? Learning Python and the online
> documentation seem fairly anemic when it comes to showing how to really
> wield dictionaries with power, and the Python Cookbook seems to assume one
> has a bit more knowledge about the language than the bundled docs
> bkd

Why not just check the old hair color before adding to the redheads list?

redheads = []

for newgirl in newdata:
    if newgirl['hair'] == 'Redhead':
        for oldgirl in olddata:
            if oldgirl['name'] == newgirl['name']:
                if oldgirl['hair'] != 'Redhead':
                    print '%s used to be a %s' % (newgirl['name'],

print redheads


Betty used to be a Blonde
Veronica used to be a Brunette
Samantha used to be a Blond
[{'hair': 'Redhead', 'role': 'Student', 'name': 'Betty'}, {'hair':
'Redhead', 'role': 'Student', 'name': 'Veronica'}, {'hair': 'Redhead',
'role': 'Witch', 'name': 'Samantha'}]

--end output--

Also, since Python's for statement iterates over a collection, it's often
cleaner to iterate directly over your list/tuple instead of using range( )
and then indexing into it.