簡體   English   中英

綜合列表和字典理解

[英]Combined list and dict comprehension

我有一些冗長的邏輯,我想用一些理解來壓縮它。

基本上,我有一個我正在閱讀的dict對象,其中有16個值,我關注它。 我通過以下理解得到了我想要的鑰匙:

["I%d" % (i,) for i in range(16)]

源字典類似於:

{ "I0": [0,1,5,2], "I1": [1,3,5,2], "I2": [5,9,10,1], ... }

我想基本上映射這個字典是這樣的:

[ 
    { "I0": 0, "I1": 1, "I2": 5, ... }
    { "I0": 1, "I1": 3, "I2": 9, ... }
    ...
]

如何使用列表和字典理解來映射事物以將我的源字典轉換為我的目的詞典列表?

這是一個功能齊全的解決方案,可以應用於任意大小。

d = { "I0": [0,1,5,2], "I1": [1,3,5,2], "I2": [5,9,10,1]}
map(dict, zip(*map(lambda (k, v): map(lambda vv: (k, vv), v), d.iteritems())))

詳細說明:(我使用ipython ,下划線_表示前一個輸出)

In [1]: d = {'I0': [0, 1, 5, 2], 'I1': [1, 3, 5, 2], 'I2': [5, 9, 10, 1]}

In [2]: map(lambda (k, v): map(lambda vv: (k, vv), v), _.iteritems())
Out[2]: 
[[('I1', 1), ('I1', 3), ('I1', 5), ('I1', 2)],
 [('I0', 0), ('I0', 1), ('I0', 5), ('I0', 2)],
 [('I2', 5), ('I2', 9), ('I2', 10), ('I2', 1)]]

In [3]: zip(*_)
Out[3]: 
[(('I1', 1), ('I0', 0), ('I2', 5)),
 (('I1', 3), ('I0', 1), ('I2', 9)),
 (('I1', 5), ('I0', 5), ('I2', 10)),
 (('I1', 2), ('I0', 2), ('I2', 1))]

In [4]: map(dict, _)
Out[4]: 
[{'I0': 0, 'I1': 1, 'I2': 5},
 {'I0': 1, 'I1': 3, 'I2': 9},
 {'I0': 5, 'I1': 5, 'I2': 10},
 {'I0': 2, 'I1': 2, 'I2': 1}]

我將如何解決它:

首先,我會為每個鍵獲取一個包含元組的列表,其中第一個項是鍵,第二個項是列表中的值之一:

>>> [ [ (k, i) for i in l] for k, l in d.items() ]
 [[('I1', 1), ('I1', 3), ('I1', 5), ('I1', 2)],
  [('I0', 0), ('I0', 1), ('I0', 5), ('I0', 2)],
  [('I2', 5), ('I2', 9), ('I2', 10), ('I2', 1)]]

然后我將使用zip函數橫切此列表,創建包含每個對應鍵的元組列表:

>>> list(zip(*[ [ (k, i) for i in l] for k, l in d.items() ]))
[(('I1', 1), ('I0', 0), ('I2', 5)),
 (('I1', 3), ('I0', 1), ('I2', 9)),
 (('I1', 5), ('I0', 5), ('I2', 10)),
  (('I1', 2), ('I0', 2), ('I2', 1))]

這些子列表可以作為參數傳遞給dict構造函數:

>>> [dict(lp) for lp in zip(*[ [ (k, i) for i in l] for k, l in d.items() ])]
[{'I0': 0, 'I1': 1, 'I2': 5},
 {'I0': 1, 'I1': 3, 'I2': 9},
 {'I0': 5, 'I1': 5, 'I2': 10},
 {'I0': 2, 'I1': 2, 'I2': 1}]

然而,在實踐中,我絕不會建議只在一行中做這樣的事情:

>>> pairs = [ [ (k, i) for i in l] for k, l in d.items() ]
>>> transversed = zip(*pairs)
>>> ds = [dict(t) for t in transversed]
>>> pprint(ds)
[{'I0': 0, 'I1': 1, 'I2': 5},
 {'I0': 1, 'I1': 3, 'I2': 9},
 {'I0': 5, 'I1': 5, 'I2': 10},
 {'I0': 2, 'I1': 2, 'I2': 1}]

實際上,我會說我發布這個答案主要是為了建議你將解決方案分成多行。

有簡短的解決方案:

keys = data.keys()
values = data.values()
transformed = [dict(zip(keys, t)) for t in zip(*values)]

這里的關鍵是轉置值矩陣,用zip(*values) ,然后我們只重建dicts。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM