-4

HI I tried using zip function to merge these to lists into a dictionary and only the last dataset is showing up . is there a better way to do it?

list_values = ['event1','location1','time1','event2','location2','time2','event3','location3','time3','event4','location4','time4']
list_keys = ['event','location','time']

Final desired output dictionary 

output = [{'event':'event1','location':'location1','time':'time1'},{'event':'event2','location':'location2','time':'time2'},{'event':'event3','location':'location3','time':'time3'},{'event':'event4','location':'location4','time':'time4'}]


Chris
  • 17
  • 1
  • 5

3 Answers3

2

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
Matthias
  • 12,873
  • 6
  • 42
  • 48
  • I like your first approach, but you don't really need `cycle()` there: `[dict(zip(list_keys, list_values[i: i + len(list_keys)])) for i in range(0, len(list_values), len(list_keys))]`. – Olvin Roght Oct 31 '20 at 14:52
  • I should say that code I've offered will be [slightly slower](https://repl.it/repls/TerrificSpiritedCode#main.py) than first two approaches. – Olvin Roght Oct 31 '20 at 15:12
0

You have to replicate the keys enough times for your input data:

import math

list_values = [
    'event1','location1','time1',
    'event2','location2','time2',
    'event3','location3','time3',
    'event4','location4','time4']
list_keys = ['event','location','time']
val_count = len(list_values)
key_count = len(list_keys)
repl = math.ceil(val_count / key_count)

enough_keys = list_keys * repl

Now you have enough keys to zip the two lists. I'll leave the "chunking" up to you. :-)

Another approach is to iterate through the values:

for pos, val in enumerate(list_values):
    key = list_keys[pos % len(list_keys)]

This will get you the key that corresponds to each value.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

if I understand you correct, you want to make multiple dictionarys out of two lists by splitting the value list.

list_values = ['event1','location1','time1','event2','location2','time2','event3','location3','time3','event4','location4','time4']
list_keys = ['event','location','time']

output=[]
for i in range(int(len(list_values)/len(list_keys))):
    output+=[dict(zip(list_keys,list_values[i:i+len(list_keys)]))]
  • Thats right I want to make multiple dictionaries out of 2 lists . Thanks for the solution and quick response – Chris Oct 30 '20 at 21:00