想象一下,我有这些 python 列表:
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
是否有直接或至少简单的方法来生成以下字典列表?
[
{'name': 'Monty', 'age': 42},
{'name': 'Matt', 'age': 28},
{'name': 'Frank', 'age': 33}
]
想象一下,我有这些 python 列表:
keys = ['name', 'age']
values = ['Monty', 42, 'Matt', 28, 'Frank', 33]
是否有直接或至少简单的方法来生成以下字典列表?
[
{'name': 'Monty', 'age': 42},
{'name': 'Matt', 'age': 28},
{'name': 'Frank', 'age': 33}
]
这是邮编方式
def mapper(keys, values):
n = len(keys)
return [dict(zip(keys, values[i:i + n]))
for i in range(0, len(values), n)]
这并不漂亮,但这是一个使用列表理解、压缩和步进的单行:
[dict(zip(keys, a)) for a in zip(values[::2], values[1::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.
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]))
zip 几乎可以满足您的需求;不幸的是,它没有循环较短的列表,而是中断了。也许有一个相关的循环功能?
这里有一个方法:
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(我认为它太聪明了),但它可能正是我们想要的。
keys
使用 循环列表没有任何好处,因为每次遍历 都对应于创建一个字典。itertools
.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:有一个具有明确目的的可读实用程序函数,其余代码自然地从中流出。
这是我的简单方法。除了我销毁输入列表之外,这似乎与@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'}]
但由你决定它是否更愚蠢。
[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ]
UG-李。我不想看到看起来像那样的代码。但它看起来是正确的。
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 )
仍然有点难看,但这些名字有助于理解它。