我有四个列表,如下所示:
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]
Run Code Online (Sandbox Code Playgroud)
lista并且listanum是同步的,listb和listbnum也.我想要一本字典,其中键都在项目listanum和值在项目lista和listb,结果将是:
di = {1: [['l','k'],['a', 'k']],
2: [['e', '3'],[]],
3:[['c','k'],['c', 'm']],
4: [['x', 'i'],['v', 'f']],
5: [['d', 'f'][]]
}
Run Code Online (Sandbox Code Playgroud)
因此,如果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])
Run Code Online (Sandbox Code Playgroud)
但得到此错误消息:'IndexError: list index out of range'.我不明白为什么它超出范围???
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'], []]}
Run Code Online (Sandbox Code Playgroud)
压缩项目,并使用collections.defaultdict默认值为lists:
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)
Run Code Online (Sandbox Code Playgroud)
我曾经chain更容易在两组键值对上进行循环; 这适用于Python 2和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']]}
Run Code Online (Sandbox Code Playgroud)
这不会为第二组创建空列表; 如果你必须有空列表,你只能构建两个单独的词典然后合并它们:
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()}
Run Code Online (Sandbox Code Playgroud)
对于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'], []]}
Run Code Online (Sandbox Code Playgroud)
具体来说,对于您的代码,您将i(索引lista)与pos以下内容混淆:
if i in listbnum:
di[pos][1].append(listb[i])
Run Code Online (Sandbox Code Playgroud)
对于i = 4,i in listbnum是True,但listb[4]不存在.您的代码也尝试附加来自lista和的列表listb,这不会导致正确的输出.
使用/ lists 的单独循环更改您的版本以使其工作:listblistbnum
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]
Run Code Online (Sandbox Code Playgroud)