Преобразования двух списков в словарь в Python
представьте, что у вас есть:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
каков самый простой способ создания следующего словаря?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
12 ответов
такой:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
вуаля :-) попарные dict
строитель zip
функция awesomely полезна:https://docs.python.org/3/library/functions.html#func-dict
попробуйте это:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
в Python 2 он также более экономичен в потреблении памяти по сравнению с zip
.
представьте, что у вас есть:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
каков самый простой способ создания следующего словаря ?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
Most performant-Python 2.7 и 3, dict понимание:
возможным улучшением использования конструктора dict является использование собственного синтаксиса понимания dict (а не понимания списка, как ошибочно выразились другие):
new_dict = {k: v for k, v in zip(keys, values)}
В Python 2, zip
возвращает список, чтобы избежать создания ненужного списка, используйте izip
вместо этого (псевдоним zip может уменьшить изменения кода при переходе на Python 3).
from itertools import izip as zip
так, что еще:
new_dict = {k: v for k, v in zip(keys, values)}
в Python 2, идеально подходит для
izip
С itertools
становится zip
в Python 3. izip
лучше, чем zip для Python 2 (потому что это позволяет избежать ненужного создания списка), и идеально подходит для 2.6 или ниже:
from itertools import izip
new_dict = dict(izip(keys, values))
Python 3
В Python 3, zip
становится той же функцией, которая была в itertools
модуль, так что просто:
new_dict = dict(zip(keys, values))
понимание Дикта было бы более эффективным, хотя (см. обзор производительности в конце этого ответа).
результат для всех случаев:
во всех случаях:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
объяснение:
если мы посмотрим на помощь на dict
мы видим, что он принимает различные формы аргументы:
>>> help(dict)
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
оптимальным подходом является использование iterable, избегая при этом создания ненужных структур данных. В Python 2 zip создает ненужный список:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
в Python 3 эквивалентом будет:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
и Python 3-х zip
просто создает итерируемый объект:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
поскольку мы хотим избежать создания ненужных структур данных, мы обычно хотим избежать Python 2 zip
(поскольку он создает ненужный список).
менее эффективные альтернативы:
это выражение генератора, передаваемое конструктору dict:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
или:
dict((k, v) for k, v in zip(keys, values))
и это понимание списка, передаваемое конструктору dict:
dict([(k, v) for k, v in zip(keys, values)])
в первых двух случаях дополнительный слой неоперативных (таким образом, ненужных) вычислений помещается над итерацией zip, а в случае понимания списка, дополнительный список создается без необходимости. Я бы ожидал, что все они будут менее результативными, и, конечно, не более.
обзор производительности:
в 64 бит Python 3.4.3, на Ubuntu 14.04, заказано от самого быстрого до самого медленного:
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.7836067057214677
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
1.0321204089559615
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
1.0714934510178864
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.6110592018812895
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.7361853648908436
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
вы также можете использовать словарь в Python ≥ 2.7:
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Если нужно преобразовать ключи или значения перед созданием словаря, то выражение генератор можно использовать. Пример:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
посмотреть код, как Pythonista: идиоматический Python.
более естественным способом является использование словарного понимания
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
С Python 3.x, идет на диктатуру
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
подробнее о дикт понимания здесь пример есть:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
для тех, кому нужен простой код и не знакомы с zip
:
List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']
Это можно сделать с помощью одной строки кода:
d = {List1[n]: List2[n] for n in range(len(List1))}
- 2018-04-18
лучшее решение по-прежнему:
In [92]: keys = ('name', 'age', 'food')
...: values = ('Monty', 42, 'spam')
...:
In [93]: dt = dict(zip(keys, values))
In [94]: dt
Out[94]: {'age': 42, 'food': 'spam', 'name': 'Monty'}
Tranpose it:
lst = [('name', 'Monty'), ('age', 42), ('food', 'spam')]
keys, values = zip(*lst)
In [101]: keys
Out[101]: ('name', 'age', 'food')
In [102]: values
Out[102]: ('Monty', 42, 'spam')
вы можете использовать этот код ниже:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
но убедитесь, что длина списков будет то же самое.если длина не одинакова.затем функция zip turncate длиннее.
метод без функции zip
l1 = {1,2,3,4,5}
l2 = {'a','b','c','d','e'}
d1 = {}
for l1_ in l1:
for l2_ in l2:
d1[l1_] = l2_
l2.remove(l2_)
break
print (d1)
{1: 'd', 2: 'b', 3: 'e', 4: 'a', 5: 'c'}