Domanda

Immagina di avere:

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

Qual è il modo più semplice per produrre il seguente dizionario?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
È stato utile?

Soluzione

In questo modo:

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

Voila :-) Il costruttore a coppie dict e la funzione zip sono incredibilmente utili: https://docs.python.org/3/library/functions.html#func-dict

Altri suggerimenti

Prova questo:

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

In Python 2, è anche più economico nel consumo di memoria rispetto a zip.

  

Immagina di avere:

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

Qual è il modo più semplice per produrre il seguente dizionario?

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

Più performante - Python 2.7 e 3, comprensione dettata:

Un possibile miglioramento nell'uso del costruttore dict consiste nell'utilizzare la sintassi nativa di una comprensione dict (non una comprensione dell'elenco, come altri l'hanno erroneamente definita):

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

In Python 2, zip restituisce un elenco, per evitare di creare un elenco non necessario, utilizzare invece izip (con aliasing zip è possibile ridurre le modifiche al codice quando si passa a Python 3).

from itertools import izip as zip

Quindi è ancora:

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

Python 2, ideale per < = 2.6

itertools da dict diventa <=> in Python 3. <=> è meglio di zip per Python 2 (perché evita la creazione di elenchi non necessari), e ideale per 2.6 o versioni precedenti:

new_dict = dict(zip(keys, values))

Python 3

In Python 3, <=> diventa la stessa funzione presente nel modulo <=>, quindi è semplicemente:

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

Una comprensione del dict sarebbe comunque più performante (vedere la revisione della performance alla fine di questa risposta).

Risultato per tutti i casi:

In tutti i casi:

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

Spiegazione:

Se guardiamo la guida su <=> vediamo che ci sono varie forme di argomenti:

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

L'approccio ottimale è utilizzare un iterabile evitando di creare strutture di dati non necessarie. In Python 2, zip crea un elenco non necessario:

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

In Python 3, l'equivalente sarebbe:

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

e Python 3 <=> crea semplicemente un oggetto iterabile:

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

Poiché vogliamo evitare di creare strutture di dati non necessarie, di solito vogliamo evitare <=> di Python 2 (poiché crea un elenco non necessario).

Alternative meno performanti:

Questa è un'espressione del generatore passata al costruttore del dict:

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

o equivalentemente:

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

E questa è una comprensione dell'elenco che viene passata al costruttore del dict:

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

Nei primi due casi, uno strato aggiuntivo di calcolo non operativo (quindi non necessario) viene posizionato sopra lo zip iterabile e, nel caso della comprensione dell'elenco, viene creato inutilmente un elenco aggiuntivo. Mi aspetterei che fossero tutti meno performanti, e certamente non di più.

Revisione delle prestazioni:

In Python 3.4.3 a 64 bit, su Ubuntu 14.04, ordinato dal più veloce al più lento:

<*>
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}

Puoi anche usare la comprensione del dizionario in Python & # 8805; 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'}

Un modo più naturale è usare la comprensione del dizionario

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}

Se devi trasformare chiavi o valori prima di creare un dizionario, allora espressione del generatore potrebbe essere usato. Esempio:

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

Dai un'occhiata Codice come un Pythonista: Idiomatic Python .

con Python 3.x, vale per la comprensione del dict

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

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

print(dic)

Altre informazioni su comprensioni qui , c'è un esempio:

>>> print {i : chr(65+i) for i in range(4)}
    {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}

Per coloro che hanno bisogno di un codice semplice e non sono & # 8217; t familiarità con zip:

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

Questo può essere fatto con una riga di codice:

d = {List1[n]: List2[n] for n in range(len(List1))}
  • 2018/4/18

La soluzione migliore è ancora:

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'}

Traspone:

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

puoi usare questo codice qui sotto:

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

Ma assicurati che la lunghezza degli elenchi sia la stessa. Se la lunghezza non è la stessa, allora la funzione zip trasforma quella più lunga.

Ecco anche un esempio di aggiunta di un valore di elenco nel tuo dizionario

list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)

assicurati sempre che la tua " Key " (list1) sia sempre nel primo parametro.

{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}

metodo senza funzione 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'}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top