2010-06-04 9 views
111

Jeden Tag liebe ich Python mehr und mehr.Pythonic Weg, etwas N-mal ohne eine Indexvariable zu tun?

Heute schreibe ich einige Code wie:

for i in xrange(N): 
    do_something() 

ich etwas N-mal zu tun hatte. Aber jedes Mal war nicht auf den Wert i (Indexvariable) angewiesen. Ich erkannte, dass ich eine Variable erstellte, die ich nie verwendete (i), und ich dachte: "Es gibt sicherlich eine pythischere Art, dies ohne die Notwendigkeit für diese nutzlose Indexvariable zu tun."

Also ... die Frage ist: Weißt du, wie man diese einfache Aufgabe auf eine (pythonisch) schöne Weise macht?

+0

Ich glaube, ich habe diese Frage schon irgendwo gesehen ... und habe die Antwort vergessen. – mpen

+7

Ich habe gerade über die Variable _ gelernt, aber ansonsten würde ich die Art und Weise betrachten, wie Sie es tun, Pythonic. Ich glaube nicht, dass ich jemals eine einfache for-Schleife gesehen habe, zumindest auf Python. Obwohl ich sicher bin, dass es bestimmte Anwendungsfälle gibt, in denen man es anschaut und sagt "Warte, das sieht schrecklich aus" - aber im Allgemeinen ist xrange der bevorzugte Weg (soweit ich es gesehen habe). –

+0

Mögliches Duplikat von [Ist es möglich, ein Python für eine Bereichsschleife ohne Iterator-Variable zu implementieren?] (Http://stackoverflow.com/questions/818828/is-it-possible-to-implement-a-python-for-- Bereich-Schleife-ohne-Iterator-Variable) –

Antwort

77

Ein etwas schneller Ansatz als auf xrange(N) Looping ist:

import itertools 

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

Wie viel schneller? Gibt es in Python 3.1 noch einen Unterschied? –

+13

@Hamish: Mein Test mit 2.6 sagt 32% schneller (23,2 us vs 17,6 us für N = 1000). Aber das ist wirklich eine Zeit Zeit.Ich würde standardmäßig auf den Code des OPs zurückgreifen, weil es für mich besser lesbar ist (für mich). –

+3

Das ist gut über die Geschwindigkeit zu wissen. Ich stimme Mike sicherlich zu, dass der OP-Code besser lesbar ist. –

41

Verwenden Sie die _ Variable, wie ich gelernt, als ich diese question gefragt, zum Beispiel:

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

Warum die Downvotes? – GreenMatt

+6

Nicht der downvoter aber es könnte sein, weil Sie auf einen anderen Beitrag beziehen, anstatt mehr Details in die Antwort hinzuzufügen – Downgoat

+2

@Downgoat: Danke für die Rückmeldung. Das heißt, über dieses Idiom gibt es nicht viel zu sagen. Ich wollte in einem anderen Beitrag darauf hinweisen, dass eine Suche die Antwort hervorgebracht haben könnte. Ich finde es ironisch, dass diese Frage mehrmals die Upvotes hat wie die andere. – GreenMatt

7

Die _ ist die gleiche Ding als x. Es ist jedoch ein Python-Idiom, das verwendet wird, um einen Bezeichner anzugeben, den Sie nicht verwenden möchten. In Python benötigen diese Bezeichner keinen Speicher wie in anderen Sprachen. Es ist leicht, das zu vergessen. Sie sind nur Namen, die auf Objekte zeigen, in diesem Fall eine Ganzzahl bei jeder Iteration.

7

seit Funktion Bürger erster Klasse ist, können Sie kleine Wrapper schreiben (von Alex antwortet)

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

dann können Sie Funktion als Argument übergeben.

+0

Ich frage mich, was die Strafe ist ... –

+0

@Hamish: Fast nichts. (17.8 us pro Schleife unter den gleichen Bedingungen wie die Zeiten für Alex Antwort, für einen 0,2 us Unterschied). –

+1

Oder, besser, 'für fn in itertools.repeat (f, N): fn()' ... – F1Rumors

25

Ich benutze einfach for _ in range(n), es ist direkt auf den Punkt. Es wird die gesamte Liste für große Zahlen in Python 2 generieren, aber wenn Sie Python 3 verwenden, ist das kein Problem.

6

Angenommen, Sie do_something als Funktion definiert haben, und Sie möchten, dass es N mal auszuführen. Vielleicht können Sie versuchen, die folgenden:

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

Sicher. Lassen Sie uns die Funktion nicht einfach eine Million Mal aufrufen, sondern auch eine Liste mit einer Million Elementen. Wenn die CPU arbeitet, sollte nicht auch der Speicher etwas gestresst sein? Die Antwort kann nicht als definitiv "nicht nützlich" (es zeigt einen anderen, funktionierenden Ansatz) gekennzeichnet werden, so dass ich nicht ablehnen kann, aber ich stimme nicht zu und ich bin total dagegen. – tzot

+1

Ist es nicht nur eine Liste von N Referenzen auf den gleichen Funktionswert? –

+0

eher besser zu tun 'fn() für fn in itertools.repeat (do_something, N)' und speichern vorgenerieren das Array ... das ist meine bevorzugte Idiom. – F1Rumors

0

Was ist eine einfache while-Schleife?

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

Sie haben bereits die Variable; warum nicht benutzen?

+1

Mein einziger Gedanke ist, dass es 3 Zeilen Code versus einem (?) – AJP

+2

@AJP - Mehr wie 4 Zeilen vs 2 Zeilen – ArtOfWarfare

+0

fügt den Vergleich (mal> 0) und die Dekrement (mal - = 1) zu den Gemeinkosten. .. so langsamer als die for-Schleife ... – F1Rumors

Verwandte Themen