6

I have two lists:

header = ["Name", "Age"]
detail = ["Joe", 22, "Dave", 43, "Herb", 32]

And would like to create a list of dictonaries like this:

[{"Name": "Joe", "Age": 22}, {"Name": "Dave", "Age": 32}, {"Name": "Herb", "Age": 32}]

This method zip gets me partially there, but only adds the first set of values to the dictionary:

>>> dict(zip(header, detail))
{'Age': 22, 'Name': 'Joe'}

How can I output as one dictionary for all values in the detail list? I found this answer, but this depends on detail containing nested lists.

Community
  • 1
  • 1
Bryan
  • 17,112
  • 7
  • 57
  • 80

4 Answers4

9
>>> detail = ["Joe", 22, "Dave", 43, "Herb", 32]
>>> d = dict(zip(detail[::2], detail[1::2]))
>>> d
{'Herb': 32, 'Dave': 43, 'Joe': 22}

For your new/edited question:

>>> d = [dict(zip(header, items)) for items in zip(detail[::2],detail[1::2])]
>>> d
[{'Age': 22, 'Name': 'Joe'}, {'Age': 43, 'Name': 'Dave'}, {'Age': 32, 'Name': 'H
erb'}]
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
2

Here's one way to get it:

header = ["Name", "Age"]
detail = ["Joe", 22, "Dave", 43, "Herb", 32]
data_iter = iter(detail)
collated = []
while True:
    next_data = zip(header, data_iter)
    if not next_data:
        break
    collated.append(dict(next_data))

output is

[{'Age': 22, 'Name': 'Joe'},
 {'Age': 43, 'Name': 'Dave'},
 {'Age': 32, 'Name': 'Herb'}]

This version has the advantage that you don't need to change the code if you change the number of headers.

Mu Mind
  • 10,935
  • 4
  • 38
  • 69
2

For such tasks I prefer functional approach.

Here is a recipe for grouper:

def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

By using it, we may advance trough detail by groups of 2:

>>> groups = grouper(len(header),detail)
>>> list(groups)
[('Joe', 22), ('Dave', 43), ('Herb', 32)]

And then we can use this iterator to create dictionaries as you need:

>>> [dict(zip(header,group)) for group in groups]
[{'Age': 22, 'Name': 'Joe'}, {'Age': 43, 'Name': 'Dave'}, {'Age': 32, 'Name': 'Herb'}]

To clarify, zip(header,group) gives this:

>>> zip(["Name", "Age"],('Joe', 22))
[('Name', 'Joe'), ('Age', 22)]

And summoning dict constructor gives this:

>>> dict([('Name', 'Joe'), ('Age', 22)])
{'Age': 22, 'Name': 'Joe'}
ovgolovin
  • 13,063
  • 6
  • 47
  • 78
1
>>> header = ["Name", "Age"]
>>> detail = ["Joe", 22, "Dave", 43, "Herb", 32]
>>> [dict(zip(header,detail[i:i+2])) for i in range(0,len(detail),2)]
[{'Age': 22, 'Name': 'Joe'}, {'Age': 43, 'Name': 'Dave'}, {'Age': 32, 'Name': 'Herb'}]`
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504