Reputation: 60831
Let's say I have a list a
in Python whose entries conveniently map to a dictionary. Each even element represents the key to the dictionary, and the following odd element is the value
for example,
a = ['hello','world','1','2']
and I'd like to convert it to a dictionary b
, where
b['hello'] = 'world'
b['1'] = '2'
What is the syntactically cleanest way to accomplish this?
Upvotes: 231
Views: 584905
Reputation: 2139
Python 3.12 introduced the itertools.batched
function. With it you can iterate the original list in batches of 2, allowing you to do something like this:
import itertools
b = dict(itertools.batched(a, 2))
Upvotes: 1
Reputation: 4137
Another option (courtesy of Alex Martelli - source):
dict(a[i:i+2] for i in range(0, len(a), 2))
Upvotes: 69
Reputation: 184365
b = dict(zip(a[::2], a[1::2]))
If a
is large, you will probably want to do something like the following, which doesn't make any temporary lists like the above.
from itertools import izip
i = iter(a)
b = dict(izip(i, i))
In Python 3 you could also use a dict comprehension, but ironically I think the simplest way to do it will be with range()
and len()
, which would normally be a code smell.
b = {a[i]: a[i+1] for i in range(0, len(a), 2)}
So the iter()/izip()
method is still probably the most Pythonic in Python 3, although as EOL notes in a comment, zip()
is already lazy in Python 3 so you don't need izip()
.
i = iter(a)
b = dict(zip(i, i))
In Python 3.8 and later you can write this on one line using the "walrus" operator (:=
):
b = dict(zip(i := iter(a), i))
Otherwise you'd need to use a semicolon to get it on one line.
Upvotes: 310
Reputation: 1160
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}
result : {'hello': 'world', '1': '2'}
Upvotes: 0
Reputation: 12679
You can also try this approach save the keys and values in different list and then use dict method
data=['test1', '1', 'test2', '2', 'test3', '3', 'test4', '4']
keys=[]
values=[]
for i,j in enumerate(data):
if i%2==0:
keys.append(j)
else:
values.append(j)
print(dict(zip(keys,values)))
output:
{'test3': '3', 'test1': '1', 'test2': '2', 'test4': '4'}
Upvotes: 0
Reputation: 39
try below code:
>>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
>>> d2
{'three': 3, 'two': 2, 'one': 1}
Upvotes: 0
Reputation: 896
You can do it pretty fast without creating extra arrays, so this will work even for very large arrays:
dict(izip(*([iter(a)]*2)))
If you have a generator a
, even better:
dict(izip(*([a]*2)))
Here's the rundown:
iter(h) #create an iterator from the array, no copies here
[]*2 #creates an array with two copies of the same iterator, the trick
izip(*()) #consumes the two iterators creating a tuple
dict() #puts the tuples into key,value of the dictionary
Upvotes: 4
Reputation: 10642
Something i find pretty cool, which is that if your list is only 2 items long:
ls = ['a', 'b']
dict([ls])
>>> {'a':'b'}
Remember, dict accepts any iterable containing an iterable where each item in the iterable must itself be an iterable with exactly two objects.
Upvotes: 17
Reputation: 91
I am also very much interested to have a one-liner for this conversion, as far such a list is the default initializer for hashed in Perl.
Exceptionally comprehensive answer is given in this thread -
Mine one I am newbie in Python), using Python 2.7 Generator Expressions, would be:
dict((a[i], a[i + 1]) for i in range(0, len(a) - 1, 2))
Upvotes: 1
Reputation: 2640
You can also do it like this (string to list conversion here, then conversion to a dictionary)
string_list = """
Hello World
Goodbye Night
Great Day
Final Sunset
""".split()
string_list = dict(zip(string_list[::2],string_list[1::2]))
print string_list
Upvotes: 1
Reputation: 1630
You can use a dict comprehension for this pretty easily:
a = ['hello','world','1','2']
my_dict = {item : a[index+1] for index, item in enumerate(a) if index % 2 == 0}
This is equivalent to the for loop below:
my_dict = {}
for index, item in enumerate(a):
if index % 2 == 0:
my_dict[item] = a[index+1]
Upvotes: 18
Reputation: 728
I am not sure if this is pythonic, but seems to work
def alternate_list(a):
return a[::2], a[1::2]
key_list,value_list = alternate_list(a)
b = dict(zip(key_list,value_list))
Upvotes: 0
Reputation: 5365
May not be the most pythonic, but
>>> b = {}
>>> for i in range(0, len(a), 2):
b[a[i]] = a[i+1]
Upvotes: 5