将两个列表映射到一个词典列表中

时间:2008-10-28 19:06:55

标签: python dictionary list

想象一下,我有这些python列表:

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]

是否有直接或至少一种简单的方法来生成以下词典列表?

[
    {'name': 'Monty', 'age': 42},
    {'name': 'Matt',  'age': 28},
    {'name': 'Frank', 'age': 33}
]

8 个答案:

答案 0 :(得分:13)

这是拉链方式

def mapper(keys, values):
    n = len(keys)
    return [dict(zip(keys, values[i:i + n]))
            for i in range(0, len(values), n)]

答案 1 :(得分:3)

这不是很漂亮,但这是一个使用列表理解,压缩和步进的单行:

[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])]

答案 2 :(得分:2)

愚蠢的方式,但是我立即想到的一个:

def fields_from_list(keys, values):
    iterator = iter(values)
    while True:
        yield dict((key, iterator.next()) for key in keys)

list(fields_from_list(keys, values)) # to produce a list.

答案 3 :(得分:2)

zip几乎可以满足您的需求;不幸的是,它不是骑自行车的短名单,而是打破了。也许有一个循环的相关功能?

$ python
>>> keys = ['name', 'age']
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
>>> dict(zip(keys, values))
{'age': 42, 'name': 'Monty'}

/编辑:哦,你想要 dict 列表。以下作品(感谢彼得,也是如此):

from itertoos import cycle

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]

x = zip(cycle(keys), values)
map(lambda a: dict(a), zip(x[::2], x[1::2]))

答案 4 :(得分:2)

Konrad Rudolph

的答案中
  拉链几乎可以做你想要的;不幸的是,它不是骑自行车的短名单,而是打破了。也许有一个循环的相关功能?

这是一种方式:

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
iter_values = iter(values)
[dict(zip(keys, iter_values)) for _ in range(len(values) // len(keys))]

我不会称之为Pythonic(我觉得它太聪明了),但它可能正在寻找。

使用itertools keys循环.cycle()列表没有任何好处,因为keys的每次遍历都对应于创建一个词典。

编辑:以下是另一种方式:

def iter_cut(seq, size):
    for i in range(len(seq) / size):
        yield seq[i*size:(i+1)*size]

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
[dict(zip(keys, some_values)) for some_values in iter_cut(values, len(keys))]

这更加pythonic:有一个具有明确目的的可读实用函数,其余代码自然地从它流出。

答案 5 :(得分:1)

这是我的简单方法。它似乎接近@Cheery的想法,除了我销毁输入列表。

def pack(keys, values):
  """This function destructively creates a list of dictionaries from the input lists."""
  retval = []
  while values:
    d = {}
    for x in keys:
      d[x] = values.pop(0)
    retval.append(d)
  return retval

答案 6 :(得分:1)

又一次尝试,可能比第一次尝试笨:

def split_seq(seq, count):
    i = iter(seq)
    while True:
        yield [i.next() for _ in xrange(count)]

>>> [dict(zip(keys, rec)) for rec in split_seq(values, len(keys))]
[{'age': 42, 'name': 'Monty'},
 {'age': 28, 'name': 'Matt'},
 {'age': 33, 'name': 'Frank'}]

但是由你来决定它是否是笨蛋。

答案 7 :(得分:0)

[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ]

UG-LEEE。我讨厌看到那样的代码。但它看起来是正确的。

def dictizer(keys, values):
   steps = xrange(0,len(values),len(keys))
   bites = ( values[n:n+len(keys)] for n in steps)
   return ( dict(zip(keys,bite)) for bite in bites )

仍然有点难看,但名字有助于理解它。