Match two lists to one dictionary list

Imagine I have these python lists:

keys = ['name', 'age'] values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 

Is there a direct or at least easy way to create the following list of dictionaries?

 [ {'name': 'Monty', 'age': 42}, {'name': 'Matt', 'age': 28}, {'name': 'Frank', 'age': 33} ] 
+6
python dictionary list
source share
8 answers

Here is the post method

 def mapper(keys, values): n = len(keys) return [dict(zip(keys, values[i:i + n])) for i in range(0, len(values), n)] 
+13
source share

This is not very, but here is one-line, using list comprehension, zip and stepping:

 [dict(zip(keys, a)) for a in zip(values[::2], values[1::2])] 
+3
source share

Dumb way, but one that comes to my mind:

 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. 
+2
source share

zip almost does what you want; Unfortunately, instead of cycling to a shorter list, it breaks down. Maybe there is a related function that is cyclical?

 $ python >>> keys = ['name', 'age'] >>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33] >>> dict(zip(keys, values)) {'age': 42, 'name': 'Monty'} 

/ EDIT: Oh, you need a dict list. The following works (thanks to Peter):

 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])) 
+2
source share

In response, Conrad Rudolph

zip almost does what you want; Unfortunately, instead of cycling to a shorter list, it breaks down. Maybe there is a related function that is cyclical?

Here is the way:

 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))] 

I will not call it Pythonic (I think it is too smart), but it may be what you need.

There is no benefit in the circular list of keys using itertools .cycle() , because each itertools .cycle() corresponds to creating one dictionary.

EDIT: Other way:

 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))] 

This is much more pythonic: there is a readable utility function with a clear purpose, and the rest of the code naturally follows from it.

+2
source share

Here is my simple approach. It seems like this is close to the idea that @Cheery, except that I destroy the input list.

 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 
+1
source share

Another attempt, perhaps dumber than the first:

 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'}] 

But it's up to you to decide whether to allow this.

+1
source share
 [dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ] 

UG-Leee. I would really like to see a code that looks like this. But it looks right.

 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 ) 

Still a little ugly, but the names help figure it out.

0
source share

All Articles