tuple - unire due liste python




Converti due liste in un dizionario in Python (8)

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

I più performanti: Python 2.7 e 3, comprensione del ditt:

Un possibile miglioramento nell'usare il costruttore di dict consiste nell'usare la sintassi nativa di una comprensione del ditt (non una comprensione di una lista, come altri hanno erroneamente detto):

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 (l'alias to zip può ridurre le modifiche al codice quando si passa a Python 3).

from itertools import izip as zip

Quindi è ancora:

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

Python 2, ideale per <= 2.6

izip da itertools diventa zip in Python 3. izip è migliore di zip per Python 2 (perché evita la creazione di liste non necessarie), e ideale per 2.6 o inferiore:

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

Python 3

In Python 3, zip diventa la stessa funzione presente nel modulo itertools , quindi è semplicemente:

new_dict = dict(zip(keys, values))

Una comprensione del ditt sarebbe tuttavia più performante (vedere la recensione delle prestazioni alla fine di questa risposta).

Risultato per tutti i casi:

In tutti i casi:

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

Spiegazione:

Se guardiamo l'aiuto su dict vediamo che ci vogliono una varietà di forme di argomenti:

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

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

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

In Python 3, l'equivalente sarebbe:

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

e lo zip Python 3 crea semplicemente un oggetto iterabile:

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

Dal momento che vogliamo evitare di creare strutture di dati non necessarie, di solito vogliamo evitare lo zip Python 2 (poiché crea un elenco non necessario).

Alternative meno performanti:

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

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

o equivalentemente:

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

E questa è una lista di comprensione che viene passata al costruttore di dict:

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

Nei primi due casi, uno strato extra di calcoli non operativi (quindi non necessari) viene posizionato sullo zip iterabile e, nel caso della comprensione dell'elenco, viene creato inutilmente un elenco aggiuntivo. Mi aspetto che tutti siano meno performanti, e certamente non di più.

Valutazione delle prestazioni:

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

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

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

Come questo:

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

Voila :-) Le funzioni di constructor e zip pairwise sono incredibilmente utili: https://docs.python.org/3/library/functions.html#func-dict


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 .


Puoi anche usare le comprensibilità del dizionario in 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'}

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

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)

Maggiori informazioni sulla comprensione del ditt qui , un esempio è lì:

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

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 di chiusura lampo sarà la più lunga.


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






dictionary