it-swarm.com.de

Ist es möglich, eine Python für eine Bereichsschleife ohne eine Iteratorvariable zu implementieren?

Ist es möglich, ohne das i zu folgen?

for i in range(some_number):
    # do something

Wenn Sie nur N-mal etwas tun möchten und den Iterator nicht benötigen.

172
James McMahon

Aus meinem 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, Sie können einfach mit der zusätzlichen Variablen i leben.

Hier ist die Option, die _ Variable, die in Wirklichkeit nur eine andere Variable ist.

for _ in range(n):
    do_something()

Beachten Sie, dass _ wird das letzte Ergebnis zugewiesen, das in einer interaktiven python session zurückgegeben wurde:

>>> 1+2
3
>>> _
3

Aus diesem Grund würde ich es nicht auf diese Weise verwenden. Mir sind keine Redewendungen bekannt, wie sie von Ryan erwähnt wurden. 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 | "_")*
96
Unknown

Möglicherweise suchen Sie nach

for _ in itertools.repeat(None, times): ...

dies ist der schnellste Weg, um times-mal in Python zu iterieren.

68
Alex Martelli

Die allgemeine Redewendung für die Zuweisung zu einem Wert, der nicht verwendet wird, lautet _.

for _ in range(times):
    do_stuff()
55
Ryan

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, dann möchten Sie Vermeiden Sie es am besten, es für andere Zwecke zu verwenden.

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, die das Datenmodell ( Py3-Link ) ausnutzt (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.

9
saffsd

Sie können _11 (oder eine beliebige Nummer oder einen anderen ungültigen Bezeichner) verwenden, um eine Namenskollision mit gettext zu verhindern. Jedes Mal, wenn Sie einen Unterstrich + einen ungültigen Bezeichner verwenden, erhalten Sie einen Dummy-Namen, der in der for-Schleife verwendet werden kann.

7
JirkaV

Möglicherweise hängt die Antwort davon ab, welches Problem Sie mit der Verwendung von Iterator 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 anzuwenden

2
Anurag Uniyal
t=0    
for _ in range(10):
    print t
    t = t+1

AUSGABE:

0
1 
2 
3 
4 
5 
6 
7
8
9
1
Imran Farid

Wenn do_something eine einfache Funktion ist oder in eine solche eingeschlossen werden kann, kann map()do_somethingrange(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 an do_something übergeben möchten, finden Sie möglicherweise auch das itertools repeatfunc-Rezept , das 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)
0
mtd

Ich stimme den oben genannten Lösungen im Allgemeinen zu. Nämlich mit:

  1. Unterstrich in for- Schleife verwenden (2 und mehr Zeilen)
  2. Einen normalen while Zähler definieren (3 und mehr Zeilen)
  3. Deklarieren einer benutzerdefinierten Klasse mit __nonzero__ Implementierung (viele weitere Zeilen)

Wenn ein Objekt wie in # 3 definiert werden soll, würde ich empfehlen, das Protokoll für das Schlüsselwort with zu implementieren oder wende contextlib an.

Weiter schlage ich noch eine andere Lösung vor. Es ist ein 3-Liner und nicht von höchster Eleganz, aber es verwendet 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 Anzahl der Iterationen der Schleife. Die Kette umschließt zwei Wiederholungsiteratoren , wobei der erste aber der zweite begrenzt ist ist unendlich. Denken Sie daran, dass dies echte Iteratorobjekte sind und daher keinen unendlichen Speicher benötigen. Offensichtlich ist dies viel langsamer als Lösung # 1 . Sofern es nicht als Teil einer Funktion geschrieben wurde, ist möglicherweise eine Bereinigung für mal Variable erforderlich.

0

Anstelle eines nicht benötigten Zählers haben Sie jetzt eine nicht benötigte Liste. Die beste Lösung ist die Verwendung einer Variablen, die mit "_" beginnt und den Syntaxprüfern mitteilt, dass Sie sich bewusst sind, dass Sie die Variable nicht verwenden.

x = range(5)
while x:
  x.pop()
  print "Work!"
0
Robert Jacobs

Wir hatten ein bisschen Spaß mit den folgenden interessanten Dingen:

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
0
Developer