2012-01-19 48 views
6

我有一些那種我想壓縮下來的一些內涵詳細的邏輯。組合列表,字典理解

從本質上講,我有我讀從具有在它的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, ... } 
    ... 
] 

我該如何映射與列表和字典解析來我的字典源轉換成字典我的目的地名單的事情?

回答

7

這是可以在任意的尺寸可以應用於一個全功能的解決方案。

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}] 
6

我將如何解決這個問題:

首先,我會得到每個鍵

>>> [ [ (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(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}] 

其實,我禾ULD說我張貼了這個答案大多建議你在多行分裂您的解決方案。

+0

1爲一步一步的闡述。我們的方法是相同的,只是我廣泛使用了'map' :) – qiao

+0

@橋是的,我們採用了更抽象的方法。我只是有一些首選列表解析,但你的解決方案是非常好的。 – brandizzi

0

有短而簡單的解決方案:

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

這裏的關鍵是換位值矩陣,這是與zip(*values)這樣做,那麼我們就重建類型的字典。