Crea un dizionario con comprensione dell'elenco


1280

Mi piace la sintassi di comprensione dell'elenco Python.

Può essere utilizzato anche per creare dizionari? Ad esempio, ripetendo le coppie di chiavi e valori:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work

Correlati: collections.Counterè un tipo specializzato di dict per il conteggio delle cose: utilizzo di un dizionario per contare gli elementi in un elenco
smci,

Risposte:


1898

Da Python 2.7 e 3 in poi, dovresti semplicemente usare la sintassi di comprensione di dict :

{key: value for (key, value) in iterable}

In Python 2.6 e precedenti, il dictbuilt-in può ricevere un iterabile di coppie chiave / valore, quindi puoi passargli una comprensione dell'elenco o un'espressione del generatore. Per esempio:

dict((key, func(key)) for key in keys)

Tuttavia, se hai già una o più iterabili di chiavi e / o val, non devi assolutamente usare una comprensione - è più semplice chiamare direttamente il dictbuilt-in:

# consumed from any iterable yielding pairs of keys/vals
dict(pairs)

# "zipped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))

1
cosa succede se ho un caso di elenco di parole ['gatto', 'cane', 'gatto'] e voglio fare un dict con chiave come parola e valore come conteggio? C'è una breve sintassi efficiente per questo?
cryanbhu,

@cryanbhu se ciò che vuoi dire è contare le ripetizioni di un dato elemento nell'elenco, c'è una classe Counter nel pacchetto collezioni: docs.python.org/2/library/collections.html#collections.Counter
fortran

237

In Python 3 e Python 2.7+, la comprensione del dizionario è simile alla seguente:

d = {k:v for k, v in iterable}

Per Python 2.6 o precedente, vedi la risposta di fortran .


57

In effetti, non è nemmeno necessario scorrere l'iterabile se comprende già un qualche tipo di mappatura, il costruttore del dict lo fa gentilmente per te:

>>> ts = [(1, 2), (3, 4), (5, 6)]
>>> dict(ts)
{1: 2, 3: 4, 5: 6}
>>> gen = ((i, i+1) for i in range(1, 6, 2))
>>> gen
<generator object <genexpr> at 0xb7201c5c>
>>> dict(gen)
{1: 2, 3: 4, 5: 6}

40

In Python 2.7, va come:

>>> list1, list2 = ['a', 'b', 'c'], [1,2,3]
>>> dict( zip( list1, list2))
{'a': 1, 'c': 3, 'b': 2}

Comprimili !


11
Questo non affronta affatto la domanda.
Jean-François Corbett,

32

Crea un dizionario con comprensione dell'elenco in Python

Mi piace la sintassi di comprensione dell'elenco Python.

Può essere utilizzato anche per creare dizionari? Ad esempio, ripetendo le coppie di chiavi e valori:

mydict = {(k,v) for (k,v) in blah blah blah}

Stai cercando la frase "comprensione dict" - in realtà è:

mydict = {k: v for k, v in iterable}

Supponendo che blah blah blahsia un iterabile di due tuple: sei così vicino. Creiamo alcuni "blah" come questo:

blahs = [('blah0', 'blah'), ('blah1', 'blah'), ('blah2', 'blah'), ('blah3', 'blah')]

Sintassi di comprensione del dict:

Ora la sintassi qui è la parte della mappatura. Ciò che rende questa una dictcomprensione invece di una setcomprensione (che è ciò che il tuo pseudo-codice approssima) sono i due punti, :come di seguito:

mydict = {k: v for k, v in blahs}

E vediamo che ha funzionato e che dovrebbe mantenere l'ordine di inserimento come da Python 3.7:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah2': 'blah', 'blah3': 'blah'}

In Python 2 e fino a 3.6, l'ordine non era garantito:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah3': 'blah', 'blah2': 'blah'}

Aggiungere un filtro:

Tutte le comprensioni presentano un componente di mappatura e un componente di filtro che è possibile fornire espressioni arbitrarie.

Quindi puoi aggiungere una parte di filtro alla fine:

>>> mydict = {k: v for k, v in blahs if not int(k[-1]) % 2}
>>> mydict
{'blah0': 'blah', 'blah2': 'blah'}

Qui stiamo solo testando se l'ultimo carattere è divisibile per 2 per filtrare i dati prima di mappare le chiavi e i valori.


23

Versione Python <2.7 (RIP, 3 luglio 2010 - 31 dicembre 2019) , procedere come segue:

d = dict((i,True) for i in [1,2,3])

Versione Python> = 2.7, procedi come segue:

d = {i: True for i in [1,2,3]}

22

Per aggiungere la risposta di @ fortran, se si desidera scorrere un elenco di chiavi key_liste un elenco di valori value_list:

d = dict((key, value) for (key, value) in zip(key_list, value_list))

o

d = {(key, value) for (key, value) in zip(key_list, value_list)}

6

Ecco un altro esempio di creazione del dizionario usando la comprensione di dict:

Quello che sto cercando di fare qui è creare un dizionario alfabetico in cui ogni coppia; è la lettera inglese e la sua posizione corrispondente nell'alfabeto inglese

>>> import string
>>> dict1 = {value: (int(key) + 1) for key, value in 
enumerate(list(string.ascii_lowercase))}
>>> dict1
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 
'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 
19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
>>> 

Notare l'uso dell'enumerato qui per ottenere un elenco di alfabeti e i loro indici nell'elenco e scambiare alfabeti e indici per generare la coppia di valori chiave per il dizionario

Spero che ti dia una buona idea del dizionario e ti incoraggi a usarlo più spesso per rendere compatto il tuo codice


1
Bella risposta - semplificata:d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)}
johnnydrama,

4

Prova questo,

def get_dic_from_two_lists(keys, values):
    return { keys[i] : values[i] for i in range(len(keys)) }

Supponiamo di avere due elenchi per paese e capitale

country = ['India', 'Pakistan', 'China']
capital = ['New Delhi', 'Islamabad', 'Beijing']

Quindi creare un dizionario dai due elenchi:

print get_dic_from_two_lists(country, capital)

L'output è così,

{'Pakistan': 'Islamabad', 'China': 'Beijing', 'India': 'New Delhi'}

9
avresti potuto usare zip
Andre Simon

2
>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

Python supporta la comprensione di dict, che consente di esprimere la creazione di dizionari in fase di esecuzione utilizzando una sintassi similmente concisa.

Una comprensione del dizionario assume la forma {chiave: valore per (chiave, valore) in iterabile}. Questa sintassi è stata introdotta in Python 3 e backportata fino a Python 2.7, quindi dovresti essere in grado di usarla indipendentemente dalla versione di Python che hai installato.

Un esempio canonico sta prendendo due elenchi e creando un dizionario in cui l'elemento in ciascuna posizione nel primo elenco diventa una chiave e l'elemento nella posizione corrispondente nel secondo elenco diventa il valore.

La funzione zip utilizzata all'interno di questa comprensione restituisce un iteratore di tuple, in cui ogni elemento nella tupla viene preso dalla stessa posizione in ciascuno degli iterabili di input. Nell'esempio sopra, l'iteratore restituito contiene le tuple ("a", 1), ("b", 2), ecc.

Produzione:

{'i': 512, 'e': 64, 'o': 2744, 'h': 343, 'l': 1331, 's': 5832, 'b': 1, 'w': 10648, ' c ': 8,' x ': 12167,' y ': 13824,' t ': 6859,' p ': 3375,' d ': 27,' j ': 729,' a ': 0,' z ' : 15625, 'f': 125, 'q': 4096, 'u': 8000, 'n': 2197, 'm': 1728, 'r': 4913, 'k': 1000, 'g': 216 , "v": 9261}


2

Questo codice creerà un dizionario usando la comprensione delle liste per più liste con valori diversi che possono essere utilizzati pd.DataFrame()

#Multiple lists 
model=['A', 'B', 'C', 'D']
launched=[1983,1984,1984,1984]
discontinued=[1986, 1985, 1984, 1986]

#Dictionary with list comprehension
keys=['model','launched','discontinued']
vals=[model, launched,discontinued]
data = {key:vals[n] for n, key in enumerate(keys)}

enumeratepasserà na valsper abbinare ciascuno keycon il suo elenco


1

Giusto per aggiungere un altro esempio. Immagina di avere il seguente elenco:

nums = [4,2,2,1,3]

e vuoi trasformarlo in un dict in cui la chiave è l'indice e il valore è l'elemento nell'elenco. Puoi farlo con la seguente riga di codice:

{index:nums[index] for index in range(0,len(nums))}

0

È possibile creare un nuovo dict per ogni coppia e unirlo al dict precedente:

reduce(lambda p, q: {**p, **{q[0]: q[1]}}, bla bla bla, {})

Ovviamente questo approccio richiede reduceda functools.


stessa idea: riduci (lambda p, q: {** p, ** dict ([q])}, bla bla bla, {})
Mahmoud Khaled,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.