We can use itertools.cycle
to repeat the keys. Then we need a list comprehension that takes the length of the key list in account and we're done.
from itertools import cycle
list_values = ['event1', 'location1', 'time1', 'event2', 'location2', 'time2',
'event3', 'location3', 'time3', 'event4', 'location4', 'time4']
list_keys = ['event', 'location', 'time']
data = list(zip(cycle(list_keys), list_values))
result = [dict(data[i:i+len(list_keys)]) for i in range(len(data))[::len(list_keys)] ]
print(result)
A more readable approach, taking the "chunks" recipe from this StackOverflow answer.
from itertools import cycle
list_values = ['event1', 'location1', 'time1', 'event2', 'location2', 'time2', 'event3', 'location3', 'time3',
'event4', 'location4', 'time4']
list_keys = ['event', 'location', 'time']
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]
data = list(zip(cycle(list_keys), list_values))
result = [dict(chunk) for chunk in chunks(data, len(list_keys))]
print(result)
One final fix. If we don't want to use up memory by creating a list with data = list(zip(cycle(list_keys), list_values))
there's a way to create chunks from the iterable we get with zip
. We have to import islice
for that. I just list the changes to the last version.
from itertools import cycle, islice # added islice
def chunks(iterable, n): # new chunk function
iterable = iter(iterable)
return iter(lambda: list(islice(iterable, n)), [])
data = zip(cycle(list_keys), list_values) # no more list