Ist es möglich, ohne das zu folgen i
?
for i in range(some_number):
# do something
Wenn Sie nur N-mal etwas tun möchten und den Iterator nicht benötigen.
Ist es möglich, ohne das zu folgen i
?
for i in range(some_number):
# do something
Wenn Sie nur N-mal etwas tun möchten und den Iterator nicht benötigen.
Antworten:
Aus dem Kopf, nein.
Ich denke, das Beste, was Sie tun können, ist so etwas:
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
Aber ich denke, man kann einfach mit der zusätzlichen i
Variablen leben.
Hier ist die Option, die _
Variable zu verwenden, die in Wirklichkeit nur eine andere Variable ist.
for _ in range(n):
do_something()
Beachten Sie, dass _
das letzte Ergebnis zugewiesen wird, das in einer interaktiven Python-Sitzung zurückgegeben wurde:
>>> 1+2
3
>>> _
3
Aus diesem Grund würde ich es nicht auf diese Weise verwenden. Mir ist keine von Ryan erwähnte Redewendung bekannt. Es kann Ihren Dolmetscher durcheinander bringen.
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
Und laut Python-Grammatik ist es ein akzeptabler Variablenname:
identifier ::= (letter|"_") (letter | digit | "_")*
_
macht deutlich, dass es ignoriert werden sollte. Zu sagen, dass es keinen Sinn macht, dies zu tun, ist wie zu sagen, dass es keinen Sinn macht, Ihren Code zu kommentieren - weil es sowieso genau das Gleiche tun würde.
Sie suchen vielleicht
for _ in itertools.repeat(None, times): ...
Dies ist DER schnellste Weg, um times
Zeiten in Python zu wiederholen .
Was jeder, der Ihnen die Verwendung von _ vorschlägt, nicht sagt, ist, dass _ häufig als Verknüpfung zu einer der gettext- Funktionen verwendet wird. Wenn Sie also möchten, dass Ihre Software in mehr als einer Sprache verfügbar ist, sollten Sie sie am besten vermeiden für andere Zwecke.
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
_
scheint diese Verwendung eine schreckliche Idee zu sein, es würde mir nichts ausmachen, damit in Konflikt zu geraten.
Hier ist eine zufällige Idee, die das Datenmodell ( Py3-Link ) nutzt (missbraucht? ).
class Counter(object):
def __init__(self, val):
self.val = val
def __nonzero__(self):
self.val -= 1
return self.val >= 0
__bool__ = __nonzero__ # Alias to Py3 name to make code work unchanged on Py2 and Py3
x = Counter(5)
while x:
# Do something
pass
Ich frage mich, ob es so etwas in den Standardbibliotheken gibt.
__nonzero__
mit Nebenwirkungen ist eine schreckliche Idee.
__call__
stattdessen verwenden. while x():
ist nicht viel schwieriger zu schreiben.
Counter
; Sicher, es ist nicht reserviert oder im eingebauten Bereich, aber es collections.Counter
ist eine Sache , und eine gleichnamige Klasse zu machen, kann zu Verwirrung führen (nicht, dass dies das nicht schon riskiert).
Sie können _11 (oder eine beliebige Nummer oder eine andere ungültige Kennung) verwenden, um eine Namenskollision mit gettext zu verhindern. Jedes Mal, wenn Sie Unterstrich + ungültige Kennung verwenden, erhalten Sie einen Dummy-Namen, der in der for-Schleife verwendet werden kann.
Möglicherweise hängt die Antwort davon ab, welches Problem Sie mit der Verwendung des Iterators haben. kann verwendet werden
i = 100
while i:
print i
i-=1
oder
def loop(N, doSomething):
if not N:
return
print doSomething(N)
loop(N-1, doSomething)
loop(100, lambda a:a)
aber ehrlich gesagt sehe ich keinen Sinn darin, solche Ansätze zu verwenden
sys.getrecursionlimit()
(der standardmäßig irgendwo in den unteren vier liegt Ziffernbereich auf CPython); using sys.setrecursionlimit
würde das Limit erhöhen, aber irgendwann würden Sie das C-Stack-Limit erreichen und der Interpreter würde mit einem Stapelüberlauf sterben (nicht nur ein nice RuntimeError
/ erhöhen RecursionError
).
t=0
for _ in range(10):
print t
t = t+1
AUSGABE:
0
1
2
3
4
5
6
7
8
9
Anstelle eines nicht benötigten Zählers haben Sie jetzt eine nicht benötigte Liste. Die beste Lösung besteht darin, eine Variable zu verwenden, die mit "_" beginnt und den Syntaxprüfern mitteilt, dass Sie wissen, dass Sie die Variable nicht verwenden.
x = range(5)
while x:
x.pop()
print "Work!"
Ich stimme im Allgemeinen den oben angegebenen Lösungen zu. Nämlich mit:
for
-loop verwenden (2 und mehr Zeilen)while
Zählers (3 und mehr Zeilen)__nonzero__
Implementierung (viele weitere Zeilen)Wenn man ein Objekt wie in # 3 definieren soll, würde ich empfehlen, das Protokoll für mit dem Schlüsselwort zu implementieren oder contextlib anzuwenden .
Weiter schlage ich noch eine andere Lösung vor. Es ist ein 3-Liner und nicht von höchster Eleganz, aber es verwendet das itertools- Paket und könnte daher von Interesse sein.
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
In diesem Beispiel ist 2 die Häufigkeit, mit der die Schleife wiederholt wird. Die Kette umschließt zwei Wiederholungsiteratoren , wobei der erste begrenzt ist, der zweite jedoch unendlich. Denken Sie daran, dass dies echte Iteratorobjekte sind und daher keinen unendlichen Speicher benötigen. Offensichtlich ist dies viel langsamer als Lösung Nr. 1 . Es sei denn als Teil einer Funktion geschrieben könnte es eine Sanierung für erforderlich Zeiten variabel.
chain
ist unnötig, times = repeat(True, 2); while next(times, False):
macht das gleiche.
Wir hatten ein bisschen Spaß mit Folgendem, interessant zu teilen:
class RepeatFunction:
def __init__(self,n=1): self.n = n
def __call__(self,Func):
for i in xrange(self.n):
Func()
return Func
#----usage
k = 0
@RepeatFunction(7) #decorator for repeating function
def Job():
global k
print k
k += 1
print '---------'
Job()
Ergebnisse:
0
1
2
3
4
5
6
---------
7
Wenn do_something
es sich um eine einfache Funktion handelt oder in eine eingewickelt werden kann, kann eine einfache map()
Dose do_something
range(some_number)
mal:
# Py2 version - map is eager, so it can be used alone
map(do_something, xrange(some_number))
# Py3 version - map is lazy, so it must be consumed to do the work at all;
# wrapping in list() would be equivalent to Py2, but if you don't use the return
# value, it's wastefully creating a temporary, possibly huge, list of junk.
# collections.deque with maxlen 0 can efficiently run a generator to exhaustion without
# storing any of the results; the itertools consume recipe uses it for that purpose.
from collections import deque
deque(map(do_something, range(some_number)), 0)
Wenn Sie Argumente übergeben möchten do_something
, finden Sie möglicherweise auch das Rezept itertoolsrepeatfunc
gut lautet:
So übergeben Sie dieselben Argumente:
from collections import deque
from itertools import repeat, starmap
args = (..., my args here, ...)
# Same as Py3 map above, you must consume starmap (it's a lazy generator, even on Py2)
deque(starmap(do_something, repeat(args, some_number)), 0)
So übergeben Sie verschiedene Argumente:
argses = [(1, 2), (3, 4), ...]
deque(starmap(do_something, argses), 0)
Wenn Sie wirklich vermeiden möchten, etwas mit einem Namen zu versehen (entweder eine Iterationsvariable wie im OP oder eine unerwünschte Liste oder ein unerwünschter Generator, der die gewünschte Zeit wahr zurückgibt), können Sie dies tun, wenn Sie wirklich möchten:
for type('', (), {}).x in range(somenumber):
dosomething()
Der verwendete Trick besteht darin, eine anonyme Klasse zu erstellen, type('', (), {})
die zu einer Klasse mit leerem Namen führt. Beachten Sie jedoch, dass diese nicht in den lokalen oder globalen Namespace eingefügt wird (selbst wenn ein nicht leerer Name angegeben wurde). Dann verwenden Sie ein Mitglied dieser Klasse als Iterationsvariable, das nicht erreichbar ist, da die Klasse, zu der es gehört, nicht erreichbar ist.
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
Entnommen aus http://docs.python.org/2/library/itertools.html
Wie wäre es mit:
while range(some_number):
#do something
range(some_number)
immer wahr ist!
some_number
es kleiner oder gleich ist, 0
ist es nicht unendlich, es läuft einfach nie. :-) Und es ist ziemlich ineffizient für eine Endlosschleife (insbesondere auf Py2), da für jeden Test ein list
neues (Py2) oder range
Objekt (Py3) erstellt wird (es ist aus Sicht des Interpreten keine Konstante, es muss geladen werden range
und some_number
jede Schleife aufrufen range
, dann das Ergebnis testen).