2013-04-12 106 views
4

的兩個列表添加到值在字典中我有一個看起來像這樣四個列表:不同長度

lista = [['l', 'k'],['e', '3'],['c', 'k'],['x', 'i'],['d', 'f']] 
listanum = [1,2,3,4,5] 
listb = [['a', 'k'],['c', 'm'],['v', 'f']] 
listbnum = [1,3,4] 

listalistanum是同步的,listblistbnum了。 我想要一本字典,其中鍵是listanum項目和值在listalistb項目,其結果將是:

di = {1: [['l','k'],['a', 'k']], 
     2: [['e', '3'],[]], 
     3:[['c','k'],['c', 'm']], 
     4: [['x', 'i'],['v', 'f']], 
     5: [['d', 'f'][]] 
} 

所以如果在數組listB listanum爲一些沒有價值,dictionarys值中的第二個列表是空的。

我已經試過這樣:

di = {} 
for i in xrange(len(lista)): 
    pos = listanum[i] 
    if pos not in di: 
    di[pos] = [[],[]] 
    di[pos][0].append(lista[i]) 
    if i in listbnum: 
    di[pos][1].append(listb[i]) 

但收到此錯誤信息:'IndexError: list index out of range'。我不明白爲什麼它超出範圍?

回答

5

郵編的項目,並使用collections.defaultdict的值默認爲list S:

from itertools import chain 
from collections import defaultdict 

di = defaultdict(list) 

for key, value in chain(zip(listanum, lista), zip(listbnum, listb)): 
    di[key].append(value) 

我以前chain使遍歷這兩組鍵值對容易的;這適用於Python 2和Python 3.如果這是僅Python 2的代碼,則可以使用+來連接兩個列表。

輸出與pprint並轉換回常規dict使打印更容易:

>>> pprint(dict(di)) 
{1: [['l', 'k'], ['a', 'k']], 
2: [['e', '3']], 
3: [['c', 'k'], ['c', 'm']], 
4: [['x', 'i'], ['v', 'f']], 
5: [['d', 'f']]} 

這不會爲第二套空列表;如果你有空列表,您僅限於建立兩個單獨的字典,然後合併這些:

dicta = dict(zip(listanum, lista)) 
dictb = dict(zip(listbnum, listb)) 

di = {k: [dicta.get(k, []), dictb.get(k, [])] for k in dicta.viewkeys() | dictb.viewkeys()} 

爲Python 2,爲Python 3使用.keys()代替.viewkeys(),生產:

>>> pprint(di) 
{1: [['l', 'k'], ['a', 'k']], 
2: [['e', '3'], []], 
3: [['c', 'k'], ['c', 'm']], 
4: [['x', 'i'], ['v', 'f']], 
5: [['d', 'f'], []]} 

具體來說,你的代碼,你糊塗i(指數爲lista)與pos

if i in listbnum: 
    di[pos][1].append(listb[i]) 

對於i = 4i in listbnumTrue,但listb[4]不存在。您的代碼也嘗試追加來自listalistb的列表,這將不會導致正確的輸出。

改變你的版本一點點工作,利用單獨循環爲listb/listbnum名單:

di = {} 
for i, pos in enumerate(listanum): 
    if pos not in di: 
     di[pos] = [[],[]] 
    di[pos][0][:] = lista[i] 

for i, pos in enumerate(listbnum): 
    di[pos][1][:] = listb[i] 
+0

會不會有一個「+」而不是一個鏈? (在這種情況下) –

+0

@JoranBeasley只在2.x –

+0

@JoranBeasley:不,如果這是Python 3. –

5
In [7]: da = dict(zip(listanum, lista)) 

In [8]: db = dict(zip(listbnum, listb)) 

In [9]: {k:[da.get(k,[]), db.get(k,[])] for k in set(listanum + listbnum)} 
Out[9]: 
{1: [['l', 'k'], ['a', 'k']], 
2: [['e', '3'], []], 
3: [['c', 'k'], ['c', 'm']], 
4: [['x', 'i'], ['v', 'f']], 
5: [['d', 'f'], []]} 
+0

+1,但我會用repalcing'設置(listanum + listbnum)'一起去'da.keys()| db.keys()'(或者在2.7中,'da.viewkeys()| db.viewkeys()')。 –

+0

@Lattyware:謝謝你的建議。我在答覆中提供的版本的觀點是它可以在2.7和3.x之間移植。 – NPE

+0

確實,儘管2to3應該愉快地將'dict.viewkeys()'轉換爲'dict.keys()'。這絕對不是什麼大問題,兩者都很可讀。 –