dict invert - learning question

George Sakkis george.sakkis at gmail.com
Sat May 3 20:57:09 EDT 2008


On May 3, 5:12 pm, dave <squareswallo... at yahoo.com> wrote:
> thanks Duncan and Arnaud.
>
> I'm learning Python from the "How to Think Like a Python Programmer"
> book by Allen Downey.  My first try used the "inv[val] = [key]" and
> then the next problem was to incorporate the "D.setdefault(...)" method.
>
> Thank you for your help.  I'm always amazed how kind people are in this group.
>
> On 2008-05-03 14:57:29 -0600, Arnaud Delobelle <arno... at googlemail.com> said:
>
> > dave <squareswallo... at y1a2hoo3.com> writes:
>
> >> Hello,
>
> >> here is a piece of code I wrote to check the frequency of values and
> >> switch them around to keys in a new dictionary.  Just to measure how
> >> many times a certain key occurs:
>
> >> def invert(d):
> >>        inv = {}
> >>        for key in d:
> >>                val = d[key]
> >>                if val not in inv:
> >>                        inv.setdefault(val, [key])
> > You can simply write:
> >                         inv[val] = [key]
> >>                else:
> >>                        inv[val].append(key)
> >>        return inv
>
> >> Using the methods above (I'm just a beginner) could I have written it
> >> more concisely?  Any criticism/critique in the code would be greatly
> >> appreciated.
>
> > Apart from the unnecessary use of setdefault, it looks good to me.
>
> > * You could change if 'val not in inv:' to 'if val in inv:' (and swap
> >   the if and else clauses of course) in order to have a positive
> >   condition rather than a negative one
>
> > * If you want to use setdefault, you can replace the if .. else
> >   construct by:
>
> >                inv.setdefault(val, []).append(key)
>
> > * You can also iterate over keys and values using the items() or
> >   iteritems() method of dictionaries:
>
> > def invert(d):
> >     inv = {}
> >     for key, val in d.iteritems():
> >         inv.setdefault(val, []).append(key)
> >     return inv
>
>

In Python 2.5 and later you may use the defaultdict class which is
faster and slightly more elegant in such cases:

from collections import defaultdict

def invert(d):
    inv = defaultdict(list)
    for key, val in d.iteritems():
        inv[val].append(key)
    return inv

George



More information about the Python-list mailing list