Преобразование двух списков в словарь
-
03-07-2019 - |
Вопрос
Представьте, что у вас есть:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
Каков самый простой способ создать следующий словарь?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
Решение
Так:
>>> 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
Другие советы
Попробуй это:
>>> 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'}
Наиболее производительный — 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
izip
от itertools
становится zip
в Python 3. izip
лучше, чем zip для Python 2 (потому что позволяет избежать создания ненужного списка) и идеально подходит для версии 2.6 или ниже:
from itertools import izip
new_dict = dict(izip(keys, values))
Питон 3
В Python 3 zip
становится той же функцией, которая была в itertools
модуль, так что это просто:
new_dict = dict(zip(keys, values))
Однако понимание dict было бы более производительным (см. обзор производительности в конце этого ответа).
Результат для всех случаев:
В любом случае:
>>> 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
>>> 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'}
Более естественный способ — использовать словарное понимание.
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
Если вам нужно преобразовать ключи или значения перед созданием словаря, тогда выражение генератора может быть использован.Пример:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
с 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'}
Транспонируйте это:
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 поменяет более длинный список.
Вот также пример добавления значения списка в словарь.
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
всегда убедитесь, что ваш «Ключ» (список1) всегда находится в первом параметре.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
метод без функции 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'}