Mit folgenden dict StrukturMehrwertige dict zur Liste der einzelnen dicts
>>> 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']
}
was wäre ein effektiver Weg, um die folgende Liste einzelner dicts zu bekommen?
>>> 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}
]
Bisher habe ich versucht:
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
die kurz nach
wurdefrom 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()))
Unter der Annahme, Python 2.7.x, in Bezug auf Leistung, was eine bessere Möglichkeit wäre?
>>> 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. Für die Neugierigen ist das erste dict ein Django MultiValue QueryDict, das viele <input>
Werte mit denselben Namen enthält.
1. aufgrund Hardcoding Werte, gemessen 3,67 Sekunden oder 6x schneller. Natürlich wird Hardcoding keine Zyklen verschwenden. 2. python 2.7 nein zip_longest aber izip_longest. Ich kann nicht sehen, wie das wiederverwendet werden könnte. –