Hi friends,
I have written a function which inverts a dictionary. The code is as follows:

def histogram(s):
    d={}
    for c in s:
        #print c, d.get(c,0)
        d[c]=d.get(c,0)+1
    return d



def invert_dict(d):
    inv={}
    for key in d:
        val=d[key]
        if val not in inv:
            inv[val]=[key]
        else :
            inv[val].append(key)
    return inv


hist=histogram('parrot')
print hist
inv=invert_dict(hist)
print inv

Now, I would like to play around with it. I would like to write a more concise function using the inbuilt setdefault() method in the dictionary module.

Definition of setdefault():{'a' is a dictionary; 'k' is a key ; 'x' is another value}
a.setdefault(k,x) : a[k] if 'k' in 'a' else settting it to x

The problem I am facing is that, I am just not able to replace the if-else loop which would actually make it more concise.
The list that it would form for a particular value is a problem. If I try creating a list appending is a problem, and if I don't the values are over-written.

Is there a way to write a more concise version or is this the best I can manage?

Thank You.

When you swap the key:value pairs you can get value to key collisions since keys have to be unique. The standard way is to but collisions into a list ...

# invert a dictionary and take care of value to key collisions

def invert_dict(d):
    inv = {}
    for k, v in d.items():
        # put collisions into a list
        inv.setdefault(v, []).append(k)
    return inv

# test it ...
d = {'a': 1, 'b': 1, 'c':1, 'd':7}
print invert_dict(d)  # {1: ['a', 'c', 'b'], 7: ['d']}

Hi ,
Thanks a lot.

I was totally unaware that this statement can be used : inv.setdefault(v, []).append(k) I got the idea.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.