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

Python 将两个列表映射到一个词典列表中,python,dictionary,list,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} ] 愚蠢的方式,但我立刻想到: def fields_fro

假设我有这些python列表:

keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
有没有一种直接的或至少是简单的方法来制作下面的词典列表

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

愚蠢的方式,但我立刻想到:

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.

zip
几乎可以满足您的需求;不幸的是,它没有循环使用较短的列表,而是中断了。也许有一个相关的函数可以循环

$ python
>>> keys = ['name', 'age']
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
>>> dict(zip(keys, values))
{'age': 42, 'name': 'Monty'}
/编辑:哦,你想要一份目录。以下作品(也感谢彼得):


这是我的简单方法。这似乎与@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

又一次尝试,也许比第一次更愚蠢:

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'}]
但这取决于你来决定是否更愚蠢。

这里是捷径

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

zip几乎可以满足你的需求;不幸的是,它没有循环使用较短的列表,而是中断了。也许有一个相关的函数可以循环

$ python
>>> keys = ['name', 'age']
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
>>> dict(zip(keys, values))
{'age': 42, 'name': 'Monty'}
这里有一个方法:

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(我认为它太聪明了),但它可能就是我们所寻找的

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

编辑:还有一种方法:

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))]

这更像是python:有一个可读的实用程序函数,目的明确,其余的代码自然地从中流出。

这并不漂亮,但这里有一个使用列表理解、压缩和步进的单行程序:

[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])]
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 )

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

这实际上并没有创建列表,而是生成元素。只需使用
list(来自列表的字段(键、值))
你说得对,一个类似zip的函数循环就可以了。
itertools.cycle
将重复一个序列。所以dict(zip(itertools.cycle(keys),values))应该可以做到。Peter,谢谢你,但我刚刚尝试过,但没有成功。它返回{'age':33,'name':'Frank'},使用l(小写的ell)作为变量名是致命的pep8冲突。您的Pythoning许可证在此被吊销!;)使用zip和slice操作符的步骤部分将这一切放在一个列表理解中:[dict(zip(key,a))对于一个in-zip(value[::2],value[1::2])]@jblocksom:这只是一个列表理解。您的方式不需要考虑多(或少)两个键@ddaa::P@guido:很高兴为您提供帮助我更改了代码格式。这是一个品味的问题,所以请随意回滚更改。我已更改“/”->“/”。因此,代码变成了Python 3.0,并与来自“未来”导入部门的
兼容。
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 )