3

Here's the original list:

['name', 'value', 'name', 'value', 'name', 'value']

And so on. I need to extract the name/value pairs into a dictionary:

{'name': 'value', 'name': 'value', 'name': 'value'}

Can someone elaborate on the easiest way to do this?

4 Answers 4

5

If L is your original list, You can use zip(*[iter(L)]*2) to group the items into pairs. The dict constructor can take an iterable of such pairs directly

>>> L = ['name1', 'value1', 'name2', 'value2', 'name3', 'value3']
>>> dict(zip(*[iter(L)]*2))
{'name1': 'value1', 'name2': 'value2', 'name3': 'value3'}

I'm not sure what you mean by simpler (simpler to understand?). It's hard to guess you think is simpler as I don't know what level you're at. Here's a way without using iter or zip. If you don't know what enumerate does yet, you should look it up.

>>> d = {}
>>> for i, item in enumerate(L):
...     if i % 2 == 0:
...         key = item
...     else:
...         d[key] = item
... 
>>> d
{'name1': 'value1', 'name2': 'value2', 'name3': 'value3'}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Would it be a bit simpler if it was known how many key/value pairs there were?
@JoshuaGilman, Knowing the length doesn't really help. I added another (longwinded) way to my answer. Is that they type of thing you mean?
Isn't this dependant on the internal implementation of zip? i.e that it tries to read one item at a time from each iterator instead of getting the first and second list eagerly?
@Maxaon3000, yes of course. It's documented behaviour
You're right this specific pattern is right there in the docs. You should probably add the link to your answer. Upvoted.
1

Not to take away from anyone. I think this might be a little simpler to understand:

dict (zip (L[::2] , L[1::2] ))

Though this is less efficient for large list than gnibbler's answer.

Comments

1

You need a function to group a sequence into fixed-length chunks. Unfortunately, this is lacking from the Python core. You could use partition from the funcy library. (Side note: In other languages this is called chunksOf or grouped).

The itertools documentation suggests this function:

from itertools import zip_longest

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

And the zip documentation suggests a different way to accomplish the same thing (given in gnibbler's answer):

def grouper(iterable, n):
    return zip(*[iter(iterable)]*n)

Once that's available, the rest of the job is trivial.

>>> dict(grouper(range(8), 2))
{0: 1, 2: 3, 4: 5, 6: 7}

Comments

0

You can try this

>>> a = ['a', 'b', 'c', 'd', 'e', 'f']
>>> dict(zip([x for x in a[::2]], [x for x in a[1::2]]))
{'a': 'b', 'c': 'd', 'e': 'f'}

a[::2] will get all second element from list start from 0th element.

a[1::2] will get all second element from list start from 1st element.

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.