Pythonic way to turn a list of strings into a dictionary with the odd-indexed strings as keys and even-indexed ones as values?
I have a list of strings parsed from somewhere, in the following format:
[key1, value1, key2, value2,开发者_如何学Python 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?
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.
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))
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'}
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.
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 :-)
精彩评论