views:

2975

answers:

6

Hi,

I'm looking for a way to convert list of tuples which looks like this:

[(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]

into a dictionary, where key:value pair looks like this:

{4:[1,2,3] ,15:[4,5,9,11,12], 23:[6,7,8,10]}

Second element from a tuple becomes a dictionary key. First tuple element is assigned to that key.

Can you show me how that can be done?

+1  A: 
l = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]
d = {}
for v, k in l:
    d.setdefault(k, []).append(v)
Chris089
By copying my use of setdefault in your edit, there are now fewer options for voters to choose from...
FogleBird
I really did not copy it. I realised I could use setdefault as well just after posting and updated by post because I liked it better.
Chris089
No problem. It's not wrong to edit to add others ideas anyway, but usually it's done to add more info, not create a duplicate answer. But I understand that you did not copy mine.
FogleBird
+1  A: 
tuples = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]
dicts = {}
for elem in tuples:
    try:
     dicts[elem[1]].append(elem[0])
    except KeyError:
     dicts[elem[1]] = [elem[0],]
Adam
Use unpacking in your for loop. And no need for a comma in a one-item list (only tuples). And using an exception here is more okay in Python than other languages but still a little silly in this case.
FogleBird
+9  A: 
>>> a = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]
>>> b = {}
>>> for i, j in a:
...     b.setdefault(j, []).append(i)
...
>>> b
{23: [6, 7, 8, 10], 4: [1, 2, 3], 15: [4, 5, 9, 11, 12]}
>>>
FogleBird
Thank you very much!
Brilliant! I just learned a new dict operation today - setdefault. That will tidy up my code a bit! Cheers. +1
Steve Folly
@Steve Folly: Look at collections.defaultdict. It's Even Better.
S.Lott
This one does not produce a list of dicts, just a dict...
martin
+2  A: 

This will do:

from collections import defaultdict

def to_list_of_dicts(list_of_tuples):
    d = defaultdict(list)
    for x, y in list_of_tuples:
        d[y].append(x)
    return sorted([{x: y} for (x, y) in d.items()])
martin
+10  A: 
>>> from collections import defaultdict
>>> l= [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]
>>> d= defaultdict( list )
>>> for v, k in l:
...     d[k].append(v)
... 
>>> d
defaultdict(<type 'list'>, {23: [6, 7, 8, 10], 4: [1, 2, 3], 15: [4, 5, 9, 11, 12]})
>>> [ {k:d[k]} for k in sorted(d) ]
[{4: [1, 2, 3]}, {15: [4, 5, 9, 11, 12]}, {23: [6, 7, 8, 10]}]
S.Lott
+1 for using defaultdict. Much smoother than calling `setdefault()` each time.
Evan Fosmark
Love collections.defaultdict. it's my go-to class for lots of work.
hughdbrown
A: 

It's not fancy but it is simple

l = [(1,4),(2,4),(3,4),(4,15),(5,15),(6,23),(7,23),(8,23),(9,15),(10,23),(11,15),(12,15)]
d = dict((k, [i[0] for i in l if i[1] == k]) for k in frozenset(j[1] for j in l))

Huzzah!

freegnu