5

我有四个看起来像这样的列表:

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]

lista并且listanum是同步的,listb也是listbnum。我想制作一个字典,其中键是项目,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 中的数字没有值,则字典值中的第二个列表为空。

我试过这个:

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'。我看不出为什么超出范围???

4

2 回答 2

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'], []]}
于 2013-04-12T14:50:37.900 回答
5

压缩项目,并使用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)

我曾经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']]}

这不会为第二组创建空列表;如果您必须有空列表,则仅限于构建两个单独的字典,然后合并它们:

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 = 4,i in listbnumTrue, 但listb[4]不存在。您的代码还尝试从and追加列表,这不会产生正确的输出。listalistb

使用/列表的单独循环稍微改变您的版本: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]
于 2013-04-12T14:50:44.250 回答