pythonpython-2.7dictionary

create a dict with unique keys and various list values from a tuple


I have a list of tuples like this one:

[('id1', 'text1', 0, 'info1'),
 ('id2', 'text2', 1, 'info2'),
 ('id3', 'text3', 1, 'info3'),
 ('id1', 'text4', 0, 'info4'),
 ('id4', 'text5', 1, 'info5'),
 ('id3', 'text6', 0, 'info6')]

I want to convert it to dict, keeping the ids as keys and all other values as lists of tuples, expanding the ones that aready exist:

{'id1': [('text1', 0, 'info1'),
         ('text4', 0, 'info4')],
 'id2': [('text2', 1, 'info2')],
 'id3': [('text3', 1, 'info3'),
         ('text6', 0, 'info6')],
 'id4': [('text5', 1, 'info5')]}

Right now I use the pretty simple code:

for x in list:
  if x[0] not in list: list[x[0]] = [(x[1], x[2], x[3])]
  else: list[x[0]].append((x[1], x[2], x[3]))

I beleive there should be more elegant way to achieve the same result, with generators maybe. Any ideas?


Solution

  • A useful method for appending to lists contained in a dictionary for these kind of problems is dict.setdefault. You can use it to retrieve an existing list from a dictionary, or add an empty one if it is missing, like so:

    data = [('id1', 'text1', 0, 'info1'),
            ('id2', 'text2', 1, 'info2'),
            ('id3', 'text3', 1, 'info3'),
            ('id1', 'text4', 0, 'info4'),
            ('id4', 'text5', 1, 'info5'),
            ('id3', 'text6', 0, 'info6')]
    
    x = {}
    for tup in data:
        x.setdefault(tup[0], []).append(tup[1:])
    

    Result:

    {'id1': [('text1', 0, 'info1'), ('text4', 0, 'info4')],
     'id2': [('text2', 1, 'info2')],
     'id3': [('text3', 1, 'info3'), ('text6', 0, 'info6')],
     'id4': [('text5', 1, 'info5')]}
    

    I actually find the setdefault method a bit awkward to use, and always forget how it works exactly. I usually use collections.defaultdict instead:

    from collections import defaultdict
    x = defaultdict(list)
    for tup in data:
        x[tup[0]].append(tup[1:])
    

    which has similar results.