Nested list to dict

Question:

I am trying to create dict by nested list:

groups = [['Group1', 'A', 'B'], ['Group2', 'C', 'D']]

L = [{y:x[0] for y in x if y != x[0]} for x in groups]
d = { k: v for d in L for k, v in d.items()}

print (d)
{'B': 'Group1', 'C': 'Group2', 'D': 'Group2', 'A': 'Group1'}

But it seems a bit complicated.

Is there a better solution?

Asked By: jezrael

||

Answers:

What about:

d = {k:row[0] for row in groups for k in row[1:]}

This gives:

>>> {k:row[0] for row in groups for k in row[1:]}
{'D': 'Group2', 'B': 'Group1', 'C': 'Group2', 'A': 'Group1'}

So you iterate over every row in the groups. The first element of the row is taken as value (row[0]) and you iterate over row[1:] to obtain all the keys k.

Weird as it might seem, this expression also works when you give it an empty row (like groups = [[],['A','B']]). That is because row[1:] will be empty and thus the row[0] part is never evaluated:

>>> groups = [[],['A','B']]
>>> {k:row[0] for row in groups for k in row[1:]}
{'B': 'A'}
Answered By: Willem Van Onsem

I think one line solution is a bit confusion. I would write code like below

groups = [['Group1', 'A', 'B'], ['Group2', 'C', 'D']]

result = {}
for group in groups:
    for item in group[1:]:
        result[item] = group[0]
print result
Answered By: Batur

This is essentially a prettier version of Willem’s:

>>> groups = [['Group1', 'A', 'B'], ['Group2', 'C', 'D']]
>>> {k:g for g,*tail in groups for k in tail}
{'B': 'Group1', 'A': 'Group1', 'C': 'Group2', 'D': 'Group2'}

But it won’t work with an empty list:groups = [[],['A','B']]

>>> {k:head for head, *tail in grps for k in tail}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <dictcomp>
ValueError: not enough values to unpack (expected at least 1, got 0)
Answered By: juanpa.arrivillaga

I also like Willem’s solution, but just for completeness…

another variation using itertools and a generator function (Python 3.x only)

def pairs(groups):
    for value,*keys in groups:
        for key_value in zip(keys, itertools.repeat(value)): 
            yield key_value

dict(pairs(groups))
{'A': 'Group1', 'B': 'Group1', 'C': 'Group2', 'D': 'Group2'}
Answered By: Marc Poulin