Convert [key1,val1,key2,val2] to a dict?
Question:
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?
Answers:
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.
May not be the most pythonic, but
>>> b = {}
>>> for i in range(0, len(a), 2):
b[a[i]] = a[i+1]
Simple answer
Another option (courtesy of Alex Martelli – source):
dict(x[i:i+2] for i in range(0, len(x), 2))
Related note
If you have this:
a = ['bi','double','duo','two']
and you want this (each element of the list keying a given value (2 in this case)):
{'bi':2,'double':2,'duo':2,'two':2}
you can use:
>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}
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))
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]
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
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))
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.
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
try below code:
>>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
>>> d2
{'three': 3, 'two': 2, 'one': 1}
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'}
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}
result : {'hello': 'world', '1': '2'}
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?
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.
May not be the most pythonic, but
>>> b = {}
>>> for i in range(0, len(a), 2):
b[a[i]] = a[i+1]
Simple answer
Another option (courtesy of Alex Martelli – source):
dict(x[i:i+2] for i in range(0, len(x), 2))
Related note
If you have this:
a = ['bi','double','duo','two']
and you want this (each element of the list keying a given value (2 in this case)):
{'bi':2,'double':2,'duo':2,'two':2}
you can use:
>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}
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))
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]
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
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))
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.
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
try below code:
>>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
>>> d2
{'three': 3, 'two': 2, 'one': 1}
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'}
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}
result : {'hello': 'world', '1': '2'}