it-swarm.com.de

Vor- und Zurückschleife Python

Ich möchte eine Endlosschleife erstellen, die von 0 bis 100 auf 0 (und so weiter) zählt und nur dann aufhört, wenn ein Konvergenzkriterium in der Schleife erfüllt ist.

for i in range(0, infinity):
    for j in range(0, 100, 1):
        print(j) # (in my case 100 lines of code)
    for j in range(100, 0, -1):
        print(j) # (same 100 lines of code as above)

Gibt es eine Möglichkeit, die beiden for-Schleifen über j in eine zu mischen, damit ich nicht den gleichen Code zweimal in die Schleifen schreiben muss?

23
Daniel

Verwenden Sie die chain-Methode von itertools

import itertools
for i in range(0, infinity):
    for j in itertools.chain(range(0, 100, 1), range(100, 0, -1)):
        print(j) # (in my case 100 lines of code)

Wie von @Chepner vorgeschlagen, können Sie itertools.cycle() für die Endlosschleife verwenden:

from itertools import cycle, chain

for i in cycle(chain(range(0, 100, 1), range(100, 0, -1))):
    ....
41
damienfrancois

Neben den anderen Antworten können Sie ein bisschen Mathematik verwenden:

while(True):
    for i in range(200):
        if i > 100:
            i = 200 - i
17
piman314

Hier ist noch eine andere Möglichkeit:

while notConverged:
    for i in xrange(-100, 101):
        print 100 - abs(i)
9
twalberg

Wenn Sie wiederholt Code verwenden, sparen Sie Platz und Aufwand mit einer Funktion:

def function(x, y, x, num_from_for_loop):
    # 100 lines of code 

while not condition:
    for i in range(1, 101):
        if condition:
            break
        function(x, y, z, i)
    for i in range(100, 0, -1):
        if condition:
            break
        function(x, y, z, i)

Sie könnten sogar einen while True verwenden

6
N Chauhan

Wenn Sie Python 3.5 oder höher verwenden, können Sie generisches Entpacken verwenden:

for j in (*range(0, 100, 1), *range(100, 0, -1)):

oder vor Python 3.5 können Sie itertools.chain verwenden:

from itertools import chain

...

for j in chain(range(0, 100, 1), range(100, 0, -1)):
3
blhsing
up = True # since we want to go from 0 to 100 first

while True: #for infinite loop

    # For up == True we will print 0-->100 (0,100,1)
    # For up == False we will print 100-->0 (100,0,-1)


    start,stop,step = (0,100,1) if up else (100,0,-1)
    for i in range(start,stop,step):
        print(i)

    up = not up # if we have just printed from 0-->100 (ie up==True), we want to print 100-->0 next so make up False ie up = not up( True) 

    # up will help toggle, between 0-->100 and 100-->0
3
Tanmay jain
def up_down(lowest_value, highest_value):
    current = lowest_value
    delta = 1
    while True: # Begin infinite loop
        yield current
        current += delta
        if current <= lowest_value or current >= highest_value:
            delta *= -1 # Turn around when either limit is hit

Dies definiert einen Generator, der so lange Werte liefert, wie Sie benötigen. Zum Beispiel:

>>> u = up_down(0, 10)
>>> count = 0
>>> for j in u:
    print(j) # for demonstration purposes
    count += 1 # your other 100 lines of code here
    if count >= 25: # your ending condition here
        break


0
1
2
3
4
5
6
7
8
9
10
9
8
7
6
5
4
3
2
1
0
1
2
3
4
1
mathmandan

Dies ist eher eine partielle Antwort als eine direkte Antwort auf Ihre Frage. Sie können jedoch auch den Begriff der trigonometrischen Funktionen und ihrer Schwingung verwenden, um eine Hin- und Her-Schleife zu imitieren.

Wenn wir eine cos-Funktion mit einer Amplitude von 100 haben, die nach links und nach oben verschoben ist, so dass f(x) = 0 und 0 <= f(x) <= 100, dann haben wir die Formel f(x) = 50(cos(x-pi)+1) (Diagramm der Grafik kann gefunden werden hier . Der Bereich ist das, was Sie brauchen, und Schwingung tritt auf, so dass keine Werte negiert werden müssen.

>>> from math import cos, pi
>>> f = lambda x: 50*(cos(x-pi)+1)
>>> f(0)
0.0
>>> f(pi/2)
50.0
>>> f(pi)
100.0
>>> f(3*pi/2)
50.0
>>> f(2*pi)
0.0

Das Problem besteht natürlich darin, dass die Funktion nicht so einfach Ganzzahlenwerte gibt, daher ist es nicht so hilfreich - aber dies kann für zukünftige Leser hilfreich sein, wenn trigonometrische Funktionen für ihren Fall hilfreich sein könnten.

0
TerryA

Ich hatte vor einiger Zeit ein ähnliches Problem, bei dem ich auch Werte in Form einer unendlichen Dreieckswelle erzeugen wollte, aber einige Werte überschreiten wollte. Ich habe am Ende einen Generator verwendet (und die Range-Funktion, wie sie auch schon verwendet wurde):

def tri_wave(min, max, step=1):
    while True:
        yield from range(min, max, step)
        yield from range(max, min, -1 * step)

Mit sorgfältig ausgewählten Werten für min, max und step (d. H. Gleichmäßig teilbar),

for value in tri_wave(0, 8, 2):
    print(value, end=", ")

Ich bekomme den min und max Wert nur einmal, was mein Ziel war:

...0, 2, 4, 6, 8, 6, 4, 2, 0, 2, 4, 6, 8, 6, 4...

Ich habe damals Python 3.6 verwendet.

0
Amoork

Ich wurde neugierig, ob es möglich ist, einen solchen Dreieckoszillator ohne Bedingungen und Aufzählungen zu implementieren. Nun, eine Möglichkeit ist folgende:

def oscillator(magnitude):
   i = 0
   x = y = -1
   double_magnitude = magnitude + magnitude

   while True:
       yield i
       x = (x + 1) * (1 - (x // (double_magnitude - 1)))  # instead of (x + 1) % double_magnitude
       y = (y + 1) * (1 - (y // (magnitude - 1)))         # instead of (y + 1) % magnitude
       difference = x - y                                 # difference ∈ {0, magnitude}
       derivative = (-1 * (difference > 0) + 1 * (difference == 0))
       i += derivative

Die Idee dahinter ist, zwei Sägezahnwellen mit unterschiedlichen Perioden zu nehmen und voneinander abzuziehen. Das Ergebnis ist eine Rechteckwelle mit Werten in {0, Magnitude}. Dann ersetzen wir einfach {0, magnitude} durch {-1, +1}, um abgeleitete Werte für unser Zielsignal zu erhalten.

Schauen wir uns das Beispiel mit magnitude = 5 an:

o = oscillator(5)
[next(o) for _ in range(21)]

Dies gibt [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0] aus.

Wenn abs() zulässig ist, kann dies der Einfachheit halber verwendet werden. Der folgende Code gibt beispielsweise die gleiche Ausgabe wie oben aus:

[abs(5 - ((x + 5) % 10)) for x in range(21)]
0
oblalex