Ist es möglich, implementieren Sie eine Python für range loop ohne eine iterator-variable?
Frage
Ist es möglich zu tun, ohne die folgenden i
?
for i in range(some_number):
# do something
Wenn Sie wollen einfach nur etwas zu tun, N Höhe der Zeit und müssen nicht den iterator.
Lösung
Aus der Spitze von meinem Kopf, nein.
Ich denke, das Beste, was Sie tun könnten so etwas wie dies:
def loop(f,n):
for i in xrange(n): f()
loop(lambda: <insert expression here>, 5)
Aber ich denke, man kann nur mit dem zusätzlichen i
Variable leben.
Dies ist die Option, die _
Variable zu verwenden, die in der Realität ist nur eine andere Variable.
for _ in range(n):
do_something()
, dass _
Hinweis wird das letzte Ergebnis zuzugeordnet, die in einer interaktiven Python-Sitzung zurückgegeben:
>>> 1+2
3
>>> _
3
Aus diesem Grunde würde ich es nicht auf diese Weise verwenden. Ich bin keine Kenntnis von einem Idiom wie von Ryan erwähnt. Es kann mess up Ihren Dolmetscher.
>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9
Und nach Python Grammatik , es ist ein akzeptabler Variablenname :
identifier ::= (letter|"_") (letter | digit | "_")*
Andere Tipps
Sie suchen können
for _ in itertools.repeat(None, times): ...
Dies ist der schnellste Weg, times
mal in Python.
Das allgemeine Idiom auf einen Wert für die Zuordnung, die nicht verwendet wird, ist es _
zu nennen.
for _ in range(times):
do_stuff()
Was jeder was darauf hindeutet, Sie _ zu verwenden ist nicht zu sagen ist, dass _ häufig als Verknüpfung zu einer der gettext Funktionen, so dass, wenn Sie möchten, dass Ihre Software in mehr als einer Sprache zur Verfügung stehen, dann sind Sie am besten dran für andere Zwecke verwenden es zu vermeiden.
import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')
Hier ist eine zufällige Idee, dass nutzt (Mißbräuche?) Das Datenmodell ( pY3 Link ).
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 wie dies in den Standardbibliotheken ist?
Sie können _11 (oder eine beliebige Anzahl oder einen anderen ungültige Bezeichner) um zu verhindern, dass Namen-colision mit gettext.Jeder Zeit Sie verwenden Unterstrich + ungültige Bezeichner erhalten Sie einen dummy-Namen, die verwendet werden können in einer for Schleife.
sein kann Antwort abhängen würde auf welches Problem Sie haben mit Iterator? kann Gebrauch sein
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 bei der Verwendung solcher Ansätze
t=0
for _ in range(10):
print t
t = t+1
OUTPUT:
0
1
2
3
4
5
6
7
8
9
Ich bin damit einverstanden allgemein mit Lösungen, die oben gegeben. Und zwar mit:
- Unterstrich in
for
-Schleife (2 und mehr Linien) - Definieren eines normalen
while
Zähler (3 und mehr Linien) - Deklarieren einer benutzerdefinierten Klasse mit
__nonzero__
Implementierung (viele weitere Linien)
Wenn man ein Objekt als in # 3 zu definieren, würde ich empfehlen, für mit Stichwort oder anwenden contextlib .
Weitere schlage ich noch eine andere Lösung. Es ist ein 3-Liner und ist nicht von höchster Eleganz, aber es nutzt itertools Paket und damit von Interesse sein könnte.
from itertools import (chain, repeat)
times = chain(repeat(True, 2), repeat(False))
while next(times):
print 'do stuff!'
In diesem Beispiel 2 ist die Anzahl, wie oft die Schleife zu durchlaufen. Kette wickeln zwei Wiederholung Iteratoren, die erste beschränkt zu sein, aber der zweite ist unendlich. Denken Sie daran, dass diese wahre Iterator-Objekte sind, damit sie nicht unendlich Speicher benötigen. Offensichtlich ist dies viel langsamer als Lösung # 1 . Es sei denn als Teil einer Funktion geschrieben, es könnte eine saubere benötigen bis zu mal Variable.
Wir haben etwas Spaß mit der folgenden hatte, interessant zu teilen, so:
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
eine einfache Funktion ist oder kann in einem, ein einfaches map()
gewickelt werden kann do_something
mal range(some_number)
:
# 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 zu übergeben do_something
möchten, können Sie auch die itertools repeatfunc
Rezept gut liest:
die gleichen Argumente zu übergeben:
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)
verschiedene Argumente zu übergeben:
argses = [(1, 2), (3, 4), ...]
deque(starmap(do_something, argses), 0)
Statt eines nicht benötigten Zähler, jetzt haben Sie eine nicht mehr benötigte Liste. Beste Lösung ist es, eine Variable zu verwenden, die mit „_“, die Syntax Checker sagt, dass Sie wissen, Sie sind die Variable nicht verwendet wird.
x = range(5)
while x:
x.pop()
print "Work!"
Wenn Sie wirklich will etwas vermeiden, dass mit einem Namen (entweder eine Iterationsvariable wie im OP oder unerwünschte Liste oder unerwünschter Generator gibt true zurück, die gewünschte Menge an Zeit) Sie könnten es tun, wenn Sie wollte wirklich:
for type('', (), {}).x in range(somenumber):
dosomething()
Der Trick, der verwendet werden ist eine anonyme Klasse type('', (), {})
zu schaffen, die mit leeren Namen in einer Klasse ergibt, aber NB, dass es nicht in dem lokalen oder globalen Namensraum eingeführt wird (auch wenn ein nicht leer Name geliefert wurde). Dann nutzen Sie ein Mitglied dieser Klasse als Iterationsvariable, die seit der Klasse nicht erreichbar ist, es ist ein Mitglied nicht erreichbar ist.
#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))
Genommen von http://docs.python.org/2/library/itertools. html
Was ist mit:
while range(some_number):
#do something