Konwertuj dwie listy do słownika w Pythonie

Wyobraź sobie, że masz:

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

Jaki jest najprostszy sposób na stworzenie poniższego słownika?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
Author: wim, 2008-10-16

12 answers

Tak:

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

Voila: -) para dict Konstruktor i zip Funkcja są niesamowicie przydatne: https://docs.python.org/3/library/functions.html#func-dict

 1452
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 14:22:35

Spróbuj tego:

>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}

W Pythonie 2 jest to również bardziej ekonomiczne zużycie pamięci w porównaniu do zip.

 110
Author: Mike Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-13 11:48:23

Wyobraź sobie, że masz:

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

Jaki jest najprostszy sposób na stworzenie poniższego słownika ?

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

Najbardziej wydajny-Python 2.7 i 3, rozumienie dict:

Możliwe ulepszenie konstruktora dict polega na użyciu natywnej składni rozumienia dict (nie rozumienia listy, jak inni błędnie to ujęli):]}
new_dict = {k: v for k, v in zip(keys, values)}

W Pythonie 2, zip zwraca listę, aby uniknąć tworzenia niepotrzebnej listy, zamiast tego użyj izip (aliased to zip może zmniejszyć zmiany kodu po przejściu do Pythona 3).

from itertools import izip as zip

Czyli nadal:

new_dict = {k: v for k, v in zip(keys, values)}

Python 2, idealny dla

izip od itertools staje się zip w Pythonie 3. izip jest lepszy niż zip Dla Pythona 2 (ponieważ unika niepotrzebnego tworzenia listy), i idealny dla 2.6 lub poniżej:

from itertools import izip
new_dict = dict(izip(keys, values))

Python 3

W Pythonie 3, zip staje się tą samą funkcją, która była w module itertools, czyli po prostu:

new_dict = dict(zip(keys, values))

Rozumienie dict byłoby jednak bardziej wydajne (patrz przegląd wydajności na końcu tej odpowiedzi).

Wynik dla wszystkich przypadków:

We wszystkich przypadkach:

>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}

Wyjaśnienie:

Jeśli spojrzymy na pomoc na dict widzimy, że przyjmuje ona różne formy argumentów:

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

Optymalnym podejściem jest użycie iterable, unikając tworzenia niepotrzebnych struktur danych. W Pythonie 2 zip tworzy niepotrzebny lista:

>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

W Pythonie 3 odpowiednikiem będzie:

>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

I zip w Pythonie 3 tylko tworzy obiekt iterowalny:

>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>

Ponieważ chcemy uniknąć tworzenia niepotrzebnych struktur danych, zwykle chcemy unikać Pythona 2 zip (ponieważ tworzy niepotrzebną listę).

Mniej wydajne alternatywy:

Jest to wyrażenie generatora przekazywane do konstruktora dict:

generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)

Lub równoważnie:

dict((k, v) for k, v in zip(keys, values))

I jest to lista przekazywana do konstruktora dict:

dict([(k, v) for k, v in zip(keys, values)])

W dwóch pierwszych przypadkach nad iterowalnym zip umieszczana jest dodatkowa warstwa niedziałających (a więc niepotrzebnych) obliczeń, a w przypadku rozumienia listy niepotrzebnie tworzona jest dodatkowa lista. Spodziewałbym się, że wszystkie będą mniej wydajne, a już na pewno nie bardziej.

Ocena wydajności:

W 64 bitowym Pythonie 3.4.3, na Ubuntu 14.04, uporządkowany od najszybszego do najwolniejszy:

>>> 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
 91
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 14:16:17
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
 29
Author: iny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-16 19:09:18

Możesz także używać składni słownikowych w Pythonie ≥ 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'}
 26
Author: Brendan Berg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-10 20:03:34

Jeśli musisz przekształcić klucze lub wartości przed utworzeniem słownika, można użyć wyrażenia generatora . Przykład:

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

Spójrz Kod jak Python: Idiomatic Python .

 13
Author: jfs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-16 20:45:04

Bardziej naturalnym sposobem jest użycie słownikowego rozumienia

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}
 10
Author: Polla A. Fattah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 02:07:00

Z Pythonem 3.x, idzie do dict

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

dic = {k:v for k,v in zip(keys, values)}

print(dic)

Więcej o dict tutaj , jest tam przykład:

>>> print {i : chr(65+i) for i in range(4)}
    {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
 9
Author: octoback,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-25 13:47:03

Dla tych, którzy potrzebują prostego kodu i nie są zaznajomieni z zip:

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

Można to zrobić za pomocą jednej linii kodu:

d = {List1[n]: List2[n] for n in range(len(List1))}
 5
Author: exploitprotocol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-28 15:18:00
  • 2018-04-18

Najlepszym rozwiązaniem jest jeszcze:

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')
 2
Author: JawSaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 02:41:00

Możesz użyć poniższego kodu:

dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))

Ale upewnij się, że długość list będzie taka sama.jeśli długość nie jest taka sama.następnie funkcja zip przekręca dłuższą.

 1
Author: Akash Nayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 13:36:39

Metoda bez funkcji 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'}
 0
Author: xiyurui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-24 05:47:22