Конвертировать два списка в словарь в Python - PullRequest
969 голосов
/ 16 октября 2008

Представьте, что у вас есть:

keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']

Какой самый простой способ создать следующий словарь?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

Ответы [ 16 ]

1741 голосов
/ 16 октября 2008

Как это:

>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}

Вуаля :-) Парный dict конструктор и zip функция очень полезны: https://docs.python.org/3/library/functions.html#func-dict

118 голосов
/ 16 октября 2008

Попробуйте это:

>>> 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.

110 голосов
/ 16 ноября 2015

Представьте, что у вас есть:

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

Какой самый простой способ создать следующий словарь?

dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

Наиболее производительный - Python 2.7 и 3, понимание слова:

Возможным улучшением при использовании конструктора 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, идеально подходит для <= 2,6 </h2> 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)

Оптимальный подход - использовать итерацию, избегая создания ненужных структур данных. В 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
30 голосов
/ 16 октября 2008
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
27 голосов
/ 11 июня 2012

Вы также можете использовать словарь в 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'}
13 голосов
/ 16 ноября 2015

Более естественным способом является использование словарного понимания

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}
12 голосов
/ 17 октября 2008

Если вам необходимо преобразовать ключи или значения перед созданием словаря, можно использовать выражение генератора . Пример:

>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3])) 

Взгляните Код Как Pythonista: Идиоматический Питон .

10 голосов
/ 25 мая 2013

в 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'}
5 голосов
/ 29 марта 2013

Для тех, кому нужен простой код и кто не знаком с zip:

List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']

Это можно сделать одной строкой кода:

d = {List1[n]: List2[n] for n in range(len(List1))}
3 голосов
/ 18 апреля 2018
  • 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...