Преобразования двух списков в словарь в 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'}