Domanda

Ho un elenco di valori e voglio metterli in un dizionario che mappare ogni valore all'indice.

Posso farlo in questo modo:

>>> t = (5,6,7)
>>> d = dict(zip(t, range(len(t))))
>>> d
{5: 0, 6: 1, 7: 2}

Questo non è male, ma sto cercando qualcosa di più elegante.

Mi sono imbattuto in quanto segue, ma fa il contrario di ciò di cui ho bisogno:

>>> d = dict(enumerate(t))
>>> d
{0: 5, 1: 6, 2: 7}

Si prega di condividere le tue soluzioni,
Grazie

MODIFICARE: Python 2.6.4

Per elenchi contenenti 1000 elementi, la versione DICT (Zip) è la più veloce, il generatore e le versioni di comprensione degli elenchi sono praticamente identiche e sono ~ 1,5 volte più lente e la mappa funzionale (invertita) è considerevolmente più lenta.

$ python -mtimeit -s "t = intervallo (int (1e3))" "d = dict (zip (t, intervallo (len (t))))"
1000 loop, il migliore di 3: 277 USEC per loop

$ python -mtimeit -s "t = intervallo (int (1e3))" "d = dict ([(y, x) per x, y in enumerate (t)])"
1000 loop, il migliore di 3: 426 USEC per loop

$ python -mtimeit -s "t = intervallo (int (1e3))" "d = dict ((y, x) per x, y in enumerate (t))"
1000 loop, il migliore di 3: 437 USEC per loop

$ python -mtimeit -s "t = intervallo (int (1e3))" "d = dict (mappa (invertita, enumerate (t))"
100 loop, il migliore di 3: 3,66 msec per loop

Ho provato a eseguire gli stessi test per elenchi più lunghi e più brevi (1e2, 1e4, 1e5) e il tempo per ciclo scale lineare in modo lineare con la lunghezza dell'elenco.

Qualcuno potrebbe tempo in versione 2.7+?

È stato utile?

Soluzione

Puoi utilizzare una comprensione dell'elenco (o un generatore, a seconda della versione Python) per eseguire un semplice scambio sul posto per il tuo secondo esempio.


Utilizzando una comprensione dell'elenco:

d = dict([(y,x) for x,y in enumerate(t)])

Usando un'espressione del generatore (Python 2.4 e in su):

d = dict((y,x) for x,y in enumerate(t))

Altri suggerimenti

In Python2.7+ puoi scriverlo in questo modo

>>> t = (5,6,7)
>>> d = {x:i for i,x in enumerate(t)}
>>> print d
{5: 0, 6: 1, 7: 2}
>>> dict((x,i) for i,x in enumerate(t))
{5: 0, 6: 1, 7: 2}
>>>

Tutti i tuoi elementi sono unici (cioè la tua lista non sarebbe mai 5,6,7,7)? La soluzione DICT funzionerà solo se tutti i tuoi elementi sono unici.

Memorizzando l'indice, stai essenzialmente duplicando informazioni, poiché potresti semplicemente interrogare l'indice corrente dell'elemento nell'elenco. Duplicare le informazioni di solito non è la migliore idea, perché consente alla possibilità che un insieme di dati non si sincronizza con l'altro.

Se l'elenco viene modificato, non c'è anche nulla che ti impedisca di assegnare accidentalmente lo stesso indice a più di un elemento.

Perché stai cercando di archiviare il valore dell'indice, quando potresti semplicemente ottenere l'indice dall'elenco?

Come tutti hanno già scritto, in Python 2.6 considererei quanto segue come il più pitone:

>>> dict((x, i) for i, x in enumerate(t))
{5: 0, 6: 1, 7: 2}

Tuttavia, in un momento di frenesia funzionale scrivo:

>>> dict(map(reversed, enumerate(t)))
{5: 0, 6: 1, 7: 2}

Mi piace il dict (zip (t, gamma (len (t))) migliore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top