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.

2
  • 2
    Why do you need the header list? You're not using it for anything. Commented Oct 2, 2012 at 14:24
  • Updated expected output in question in to include header values. Sorry for the confusion :/ Commented Oct 2, 2012 at 14:30

4 Answers 4

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'}]
Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

Might be better to use len(header) instead of 2 since you have it.
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.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.