Ist es möglich, implementieren Sie eine Python für range loop ohne eine iterator-variable?

StackOverflow https://stackoverflow.com/questions/818828

  •  03-07-2019
  •  | 
  •  

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.

War es hilfreich?

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.

iterieren

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:

  1. Unterstrich in for-Schleife (2 und mehr Linien)
  2. Definieren eines normalen while Zähler (3 und mehr Linien)
  3. 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top