拥有以下 dict 结构
>>> d = {
'email': ['e_val1', 'e_val2', 'e_val3', 'e_val4', 'e_val5'],
'id' : ['i_val1', 'i_val2', 'i_val3', 'i_val4'],
'ref' : ['r_val1', 'r_val2', 'r_val3', 'r_val4']
}
获取以下列表单个词汇的有效方法是什么?
>>> l = [
{'email': 'e_val1', 'id': 'i_val1', 'ref': 'r_val1'},
{'email': 'e_val2', 'id': 'i_val2', 'ref': 'r_val2'},
{'email': 'e_val3', 'id': 'i_val3', 'ref': 'r_val3'},
{'email': 'e_val4', 'id': 'i_val4', 'ref': 'r_val4'},
{'email': 'e_val5', 'id': None, 'ref': None}
]
到目前为止,我试过了:
def split(d):
l, longest = [], False
for k, v in d.items():
longest = max(longest, len(v))
for pointer in range(longest):
r = {}
for k, v in d.items():
try:
r[k] = v[pointer]
except IndexError:
# current list is shorter than longest
r[k] = None
l.append(r)
return l
后不久
from itertools import izip_longest
def split(d):
"""
With Python < 2.7,
- itertools.izip_longest(*d.values())
might be substituted by map with None:
- map(None, *d.values())
"""
_zipper = lambda keys: lambda v: dict(zip(keys, v))
lmb = _zipper(d.keys())
return map(lmb,
itertools.izip_longest(*d.values()))
假设Python 2.7.x在性能方面有什么更好的方法?
>>> from timeit import timeit
>>> # with map
>>> timeit(setup="""
... d={'email': ['e_val1', 'e_val2', 'e_val3', 'e_val4', 'e_val5'],
... 'id': ['i_val1', 'i_val2', 'i_val3', 'i_val4'],
... 'ref': ['r_val1', 'r_val2', 'r_val3', 'i_val4']};
... _zipper=lambda keys: lambda v: dict(zip(keys, v))""",
... stmt="""
... lmb=_zipper(d.keys());
... map(lmb, map(None, *d.values()))""")
16.14903998374939
>>> # with itertools.izip_longest
>>> timeit(setup="""
... d={'email': ['e_val1', 'e_val2', 'e_val3', 'e_val4', 'e_val5'],
... 'id': ['i_val1', 'i_val2', 'i_val3', 'i_val4'],
... 'ref': ['r_val1', 'r_val2', 'r_val3', 'i_val4']};
... _zipper=lambda keys: lambda v: dict(zip(keys, v))""",
... stmt="""
... lmb=_zipper(d.keys());
... map(lmb, izip_longest(*d.values()))""")
18.98265790939331
P.S。对于那些好奇的,初始dict是一个Django MultiValue QueryDict,包含许多具有相同名称的<input>
值。
答案 0 :(得分:4)
使用itertools.zip_longest
和列表理解:
[{'email': i, 'id': j, 'ref': k} for (i, j, k) in itertools.zip_longest(d.get('email'), d.get('id'), d.get('ref'))]
示例:强>
>>> d
{'ref': ['r_val1', 'r_val2', 'r_val3', 'r_val4'], 'id': ['i_val1', 'i_val2', 'i_val3', 'i_val4'], 'email': ['e_val1', 'e_val2', 'e_val3', 'e_val4', 'e_val5']}
>>> [{'email': i, 'id': j, 'ref': k} for (i, j, k) in itertools.zip_longest(d.get('email'), d.get('id'), d.get('ref'))]
[{'ref': 'r_val1', 'id': 'i_val1', 'email': 'e_val1'}, {'ref': 'r_val2', 'id': 'i_val2', 'email': 'e_val2'}, {'ref': 'r_val3', 'id': 'i_val3', 'email': 'e_val3'}, {'ref': 'r_val4', 'id': 'i_val4', 'email': 'e_val4'}, {'ref': None, 'id': None, 'email': 'e_val5'}]
答案 1 :(得分:0)
没有硬编码值: 时间:5.15033793449
def form_dict(key_index):
each_dict = {}
for k in d.keys():
if key_index < len(d[k]):
each_dict[k] = d[k][key_index]
else:
each_dict[k] = None
return each_dict
def get_converted_list():
Max = max([len(v) for v in d.values()])
return map(form_dict, range(0, Max))