2012-08-16 13 views
11

Eventuali duplicati:
Only index needed: enumerate or (x)range?range (len (elenco)) o enumerate (elenco)?

Quale di questi potrebbe essere considerato migliore/più chiaro/più veloce/piu 'Pythonic'? Non mi interessa il contenuto della lista L, quanto è lungo.

a = [f(n) for n, _ in enumerate(L)] 

o

a = [f(n) for n in range(len(L))] 

Se fa alcuna differenza, la funzione f fa uso di len(list) pure.

+0

quale versione di python stai usando? –

+0

@InbarRose - 2.7 –

risposta

18

alcune piste di temporizzazione veloci sembrano dare il 2 ° opzione utilizzando range() un leggero vantaggio rispetto enumerate():

timeit a = [f(n) for n, _ in enumerate(mlist)] 
10000 loops, best of 3: 118 us per loop 

timeit a = [f(n) for n in range(len(mlist))] 
10000 loops, best of 3: 102 us per loop 

e solo per divertimento usando xrange() (Python v2.7.2)

timeit a = [f(n) for n in xrange(len(mlist))] 
10000 loops, best of 3: 99 us per loop 

lo farei favorire il codice leggibile prima, quindi utilizzare xrange() se disponibile (ad esempio, Pre-Python v 3.x), seguito da range() e enumerate().

+0

enumerate è più veloce quando si desidera accedere ripetutamente agli elementi della lista nel proprio indice. Quando vuoi solo una lista di indici, è più veloce usare len() e range/xrange. –

4

La soluzione dell'intervallo (x) è più veloce, perché ha un sovraccarico minore, quindi lo userei.

In Python 2.x, utilizzare xrange anziché range, perché xrange utilizza meno memoria, perché non crea un elenco temporaneo. In Python 3.x, c'è solo range, che è la versione con meno memoria.

+0

'xrange' è un oggetto generatore? La [documentazione] (http://docs.python.org/library/functions.html#xrange) non fa menzione di quella parola, anche se la tua descrizione sembra così. –

+2

Non è un oggetto generatore (cioè un puro codice Python con 'yield' nel suo corpo), ma è equivalente a quello, implementato in C. Ha un metodo' .next() 'che restituisce il valore successivo o solleva StopIteration, e il ciclo 'for' chiama ripetutamente questo metodo' .next() '. (Si prega di votare la mia risposta se lo trovi utile.) – pts

0

Direi che poiché non si utilizza l'attributo "_" della funzione enumarata, utilizzare l'intervallo in quanto è più leggibile in questo modo.

1

Supponendo che si stia utilizzando Python 2.x, se si utilizza len(), è necessario utilizzare xrange() in quanto eviterà di creare un elenco di numeri nell'intervallo.

E in questo caso, andrei con len() perché si utilizzano gli indici, non gli elementi nell'elenco.