web-dev-qa-db-ja.com

辞書に入れ子になったリスト

ネストされたdictによって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'}

しかし、少し複雑なようです。

より良い解決策はありますか?

21
jezrael

何について:

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

これは与える:

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

したがって、rowの-​​every groupsを反復処理します。行の最初の要素は値(row[0])として取得され、row[1:]を反復してすべてのキーkを取得します。

奇妙に思われるかもしれませんが、空の行(groups = [[],['A','B']]など)を指定すると、この式も機能します。これは、row[1:]が空になるため、row[0]部分がneverと評価されるためです。

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

これは基本的にウィレムのよりきれいなバージョンです:

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

しかし、空のリストでは機能しません: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)
8

1行のソリューションは少し混乱していると思います。以下のようなコードを書きます

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

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

ウィレムのソリューションも気に入っていますが、完全を期すために...

itertoolsとジェネレーター関数を使用した別のバリエーション(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'}
4
Marc Poulin