2017-04-05 38 views
16

próbuję tworzyć dict przez zagnieżdżonego list:zagnieżdżonych list do dict

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'} 

Ale wydaje się nieco skomplikowane.

Czy istnieje lepsze rozwiązanie?

+11

widzę co robiłeś tam :) http://stackoverflow.com/a/43227053/5811078 – zipa

Odpowiedz

18

Co o:

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

daje to:

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

Więc iteracyjnego każdy row w groups. Pierwszy element wiersza jest traktowany jako wartość (row[0]), a następnie następuje iteracja ponad row[1:], aby uzyskać wszystkie klucze k.

Dziwne, jak mogłoby się wydawać, to wyrażenie również działa po podaniu pustego wiersza (np. groups = [[],['A','B']]). To dlatego row[1:] będzie pusta, a zatem row[0] część jest nigdy oceniane:

>>> groups = [[],['A','B']] 
>>> {k:row[0] for row in groups for k in row[1:]} 
{'B': 'A'} 
6

Myślę jedno rozwiązanie linia jest nieco zamieszania. Chciałbym napisać kod jak poniżej

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

result = {} 
for group in groups: 
    for item in group[1:]: 
     result[item] = group[0] 
print result 
+0

znacznie lepiej. W większości przypadków rozwiązania 1-liniowe mają jedynie pokazać spryt – Jagannath

8

Jest to zasadniczo ładniejsza wersja Willem użytkownika:

>>> 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'} 

Ale to nie będzie działać z pustej listy: 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) 
4

ja również podobnie jak rozwiązanie Willema, ale tylko dla kompletności ...

inna odmiana za pomocą itertool s oraz funkcję generatora (tylko Python 3.x)

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'}