2010-06-04 11 views
111

Ogni giorno amo sempre di più il pitone.modo pitone per fare qualcosa N volte senza una variabile indice?

Oggi, stavo scrivendo un po 'di codice come:

for i in xrange(N): 
    do_something() 

che dovevo fare qualcosa di N volte. Ma ogni volta non dipendeva dal valore di i (variabile indice). Mi sono reso conto che stavo creando una variabile che non ho mai usato (i), e ho pensato "C'è sicuramente un modo più plateale di farlo senza la necessità di quella inutile variabile dell'indice".

Quindi ... la domanda è: sai come eseguire questo semplice compito in un modo più (pitonico) bello?

+0

Penso di aver visto questa domanda da qualche parte prima ... e ho dimenticato la risposta. – mpen

+7

Ho appena saputo della variabile _, ma altrimenti prenderei in considerazione il modo in cui lo stai facendo Pythonic. Non penso di aver mai visto un semplice ciclo per un altro modo, almeno in Python. Anche se sono sicuro che ci sono casi d'uso specifici in cui lo guardi e dici "Aspetta, sembra terribile" - ma in generale, xrange è il modo preferito (per quanto ho visto). –

+0

Possibile duplicato di [È possibile implementare un Python per il loop range senza una variabile iteratore?] (Http://stackoverflow.com/questions/818828/is-it-possibile-per-implementare-a-python-for- range-loop-without-an-iterator-variable) –

risposta

77

Un approccio leggermente più veloce di loop su xrange(N) è:

import itertools 

for _ in itertools.repeat(None, N): 
    do_something() 
+1

Quanto più veloce? C'è ancora una differenza in Python 3.1? –

+13

@Hamish: il mio test con 2.6 dice il 32% più veloce (23,2 us contro 17,6 us per N = 1000). Ma questo è davvero un tempo comunque.Avrei impostato di default sul codice dell'OP perché è più immediatamente leggibile (per me). –

+3

È bello sapere della velocità. Certamente riecheggia il sentimento di Mike sul fatto che il codice dell'OP sia più leggibile. –

41

utilizzare la variabile _, come ho imparato quando ho chiesto questo question, ad esempio:

# A long way to do integer exponentiation 
num = 2 
power = 3 
product = 1 
for _ in xrange(power): 
    product *= num 
print product 
+0

Perché i downvotes? – GreenMatt

+6

Non è il downvoter, ma potrebbe essere perché ti stai riferendo a un altro post invece di aggiungere ulteriori dettagli nella risposta – Downgoat

+2

@Downgoat: Grazie per il feedback. Detto questo, non c'è molto da dire su questo idioma. Il mio punto in riferimento a un altro post è stato quello di sottolineare che una ricerca potrebbe aver prodotto la risposta. Trovo paradossale che questa domanda abbia più volte l'upvotes dell'altra. – GreenMatt

7

Il _ è la stessa cosa come x. Tuttavia è un idioma python che viene utilizzato per indicare un identificatore che non si intende utilizzare. In Python questi identificatori non memorizzano o allocano spazio come le variabili fanno in altre lingue. È facile dimenticarlo. Sono solo nomi che puntano agli oggetti, in questo caso un numero intero a ogni iterazione.

7

poiché funzione è di prima classe dei cittadini, è possibile scrivere piccolo involucro (da Alex risponde)

def repeat(f, N): 
    for _ in itertools.repeat(None, N): f() 

allora si può passare la funzione come argomento.

+0

Mi chiedo quale sia la penalità ... –

+0

@ Hamish: Quasi nulla. (17,8 us per loop nelle stesse condizioni dei tempi per la risposta di Alex, per una differenza di 0,2 ci). –

+1

O, meglio, 'per fn in itertools.repeat (f, N): fn()' ... – F1Rumors

25

Io uso solo for _ in range(n), è direttamente al punto. Genererà l'intera lista per numeri enormi in Python 2, ma se stai usando Python 3 non è un problema.

6

suppone che sia stato definito fai_qualcosa come una funzione, e ti piacerebbe eseguirla N volte. forse si può provare il seguente:

todos = [do_something] * N 
for doit in todos: 
    doit() 
+35

Sicuro. Non limitiamoci a chiamare la funzione un milione di volte, assegniamo anche una lista di un milione di articoli. Se la CPU funziona, la memoria non dovrebbe essere stressata un po '? La risposta non può essere definita come decisamente "non utile" (sta mostrando un approccio diverso e funzionante), quindi non posso parlare a valle, ma non sono d'accordo e sono totalmente contrario. – tzot

+1

Non è solo una lista di N riferimenti allo stesso valore di funzione? –

+0

è meglio fare 'fn() per fn in itertools.repeat (do_something, N)' e salvare pre-generare l'array ... questo è il mio idioma preferito. – F1Rumors

0

Che dire di un semplice ciclo while?

while times > 0: 
    do_something() 
    times -= 1 

Hai già la variabile; perché non usarlo?

+1

Il mio unico pensiero è che si tratta di 3 righe di codice rispetto a uno (?) – AJP

+2

@AJP - Più come 4 linee vs 2 righe – ArtOfWarfare

+0

aggiunge il confronto (volte> 0) e il decremento (volte - = 1) ai costi generali. .. così più lento del ciclo for ... – F1Rumors

Problemi correlati