Pythonic way to turn a list of strings into a dict

2019-06-16 20:39发布

I have a list of strings parsed from somewhere, in the following format:

[key1, value1, key2, value2, key3, value3, ...]

I'd like to create a dictionary based on this list, like so:

{key1:value1, key2:value2, key3:value3, ...}

An ordinary for loop with index offsets would probably do the trick, but I wonder if there's a Pythonic way of doing this. List comprehensions seem interesting, but I can't seem to find out how to apply them to this particular problem.

Any ideas?

5条回答
Juvenile、少年°
2楼-- · 2019-06-16 20:44
result = dict(grouper(2, L))

grouper is a function that forms pairs in a list, it's given in the itertools receipes:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

dict takes a list of (key,value) pairs and makes a dict from them.

You could also write result = dict(zip(*[iter(L)]*2)) and confuse most readers :-)

查看更多
爷、活的狠高调
3楼-- · 2019-06-16 20:52

In addition to pavpanchekha's short and perfectly fine solution, you could use a generator expression (a list comprehensions is just a generator expression fed to the list constructor - it's actually more powerful und universal) for extra goodness:

dict((l[i], l[l+1]) for i in range(0, len(l)-1, 2))

Apart from being really cool and functional, it's also a better algorithm: Unless the implementation of dict is especially stupid (unlikely considered it's a built-in), this will consume the same amount of memory for every size of l (i.e. runs in constant aka O(1) space) since it processes one pair at a time instead of creating a whole new list of tuples first.

查看更多
Rolldiameter
4楼-- · 2019-06-16 20:54

A nice opportunity to display my favorite python idiom:

>>> S = [1,2,3,4,5,6]
>>> dict(zip(*[iter(S)]*2))
{1: 2, 3: 4, 5: 6}

That tricky line passes two arguments to zip() where each argument is the same iterator over S. zip() creates 2-item tuples, pulling from the iterator over zip each time. dict() then converts those tuples to a dictionary.

To extrapolate:

S = [1,2,3,4,5,6]

I = iter(S)
dict(zip(I,I))
查看更多
Deceive 欺骗
5楼-- · 2019-06-16 21:05

You can try:

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

Explanation: we split the list into two lists, one of the even and one of the odd elements, by taking them by steps of two starting from either the first or the second element (that's the l[::2] and l[1::2]). Then we use the zip builtin to the two lists into one list of pairs. Finally, we call dict to create a dictionary from these key-value pairs.

This is ~4n in time and ~4n in space, including the final dictionary. It is probably faster than a loop, though, since the zip, dict, and slicing operators are written in C.

查看更多
淡お忘
6楼-- · 2019-06-16 21:08
In [71]: alist=['key1', 'value1', 'key2', 'value2', 'key3', 'value3']

In [72]: dict(alist[i:i+2] for i in range(0,len(alist),2))
Out[72]: {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
查看更多
登录 后发表回答