来回循环Python
Back and forth loop Python
我想创建一个无限循环,从 0 到 100 到 0(依此类推)向上和向下计数,并且仅在满足循环内的某些收敛标准时停止,所以基本上是这样的:
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)
有什么方法可以将 j 上的两个 for 循环合并为一个,这样我就不会在循环中写出相同的代码两次吗?
如果您使用的是 Python 3.5+,您可以使用通用解包:
for j in (*range(0, 100, 1), *range(100, 0, -1)):
或 Python 3.5 之前,您可以使用 itertools.chain
:
from itertools import chain
...
for j in chain(range(0, 100, 1), range(100, 0, -1)):
使用itertools
的chain
方法
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)
根据@Chepner 的建议,您可以使用 itertools.cycle()
进行无限循环:
from itertools import cycle, chain
for i in cycle(chain(range(0, 100, 1), range(100, 0, -1))):
....
除了其他答案,您还可以使用一些数学知识:
while(True):
for i in range(200):
if i > 100:
i = 200 - i
如果您有一组重复的代码,请使用函数来节省 space 和精力:
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)
你甚至可以使用 while True
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
还有另一种可能性:
while notConverged:
for i in xrange(-100, 101):
print 100 - abs(i)
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
这定义了一个生成器,只要您需要,它将继续生成值。例如:
>>> 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
这是对您问题的部分回答,而不是直接回答,但您也可以使用三角函数的概念及其振荡来模仿 'back and forth' 循环。
如果我们有一个振幅为 100 的 cos 函数,向左和向上移动使得 f(x) = 0
和 0 <= f(x) <= 100
,那么我们有公式 f(x) = 50(cos(x-pi)+1)
(图表的情节可能找到here。范围是你需要的,并且会发生振荡,所以不需要取反任何值。
>>> 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
问题当然在于该函数不会轻易给出整数值,因此它没有那么有用 - 但这可能对未来的读者有用,因为三角函数可能对他们的情况有帮助。
前段时间我遇到了类似的问题,我也想以无限三角波的形式创建值,但想跨过一些值。我最终使用了一个生成器(其他人也一直在使用范围函数):
def tri_wave(min, max, step=1):
while True:
yield from range(min, max, step)
yield from range(max, min, -1 * step)
在最小值、最大值和步长上精心选择值(即可整除),
for value in tri_wave(0, 8, 2):
print(value, end=", ")
我只得到一次最小值和最大值,这是我的目标:
...0, 2, 4, 6, 8, 6, 4, 2, 0, 2, 4, 6, 8, 6, 4...
我当时用的是Python3.6
我很好奇是否可以在没有条件和枚举的情况下实现这种三角振荡器。那么,一种选择如下:
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
这背后的想法是取 2 个不同周期的锯齿波,然后从另一个中减去。结果将是值为 {0, magnitude} 的方波。然后我们只需将 {0, magnitude} 分别替换为 {-1, +1} 以获得目标信号的导数值。
让我们看一下 magnitude = 5
的例子:
o = oscillator(5)
[next(o) for _ in range(21)]
这输出 [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
.
如果允许abs()
,可以简单使用。例如,以下代码给出与上面相同的输出:
[abs(5 - ((x + 5) % 10)) for x in range(21)]
我想创建一个无限循环,从 0 到 100 到 0(依此类推)向上和向下计数,并且仅在满足循环内的某些收敛标准时停止,所以基本上是这样的:
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)
有什么方法可以将 j 上的两个 for 循环合并为一个,这样我就不会在循环中写出相同的代码两次吗?
如果您使用的是 Python 3.5+,您可以使用通用解包:
for j in (*range(0, 100, 1), *range(100, 0, -1)):
或 Python 3.5 之前,您可以使用 itertools.chain
:
from itertools import chain
...
for j in chain(range(0, 100, 1), range(100, 0, -1)):
使用itertools
chain
方法
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)
根据@Chepner 的建议,您可以使用 itertools.cycle()
进行无限循环:
from itertools import cycle, chain
for i in cycle(chain(range(0, 100, 1), range(100, 0, -1))):
....
除了其他答案,您还可以使用一些数学知识:
while(True):
for i in range(200):
if i > 100:
i = 200 - i
如果您有一组重复的代码,请使用函数来节省 space 和精力:
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)
你甚至可以使用 while True
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
还有另一种可能性:
while notConverged:
for i in xrange(-100, 101):
print 100 - abs(i)
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
这定义了一个生成器,只要您需要,它将继续生成值。例如:
>>> 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
这是对您问题的部分回答,而不是直接回答,但您也可以使用三角函数的概念及其振荡来模仿 'back and forth' 循环。
如果我们有一个振幅为 100 的 cos 函数,向左和向上移动使得 f(x) = 0
和 0 <= f(x) <= 100
,那么我们有公式 f(x) = 50(cos(x-pi)+1)
(图表的情节可能找到here。范围是你需要的,并且会发生振荡,所以不需要取反任何值。
>>> 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
问题当然在于该函数不会轻易给出整数值,因此它没有那么有用 - 但这可能对未来的读者有用,因为三角函数可能对他们的情况有帮助。
前段时间我遇到了类似的问题,我也想以无限三角波的形式创建值,但想跨过一些值。我最终使用了一个生成器(其他人也一直在使用范围函数):
def tri_wave(min, max, step=1):
while True:
yield from range(min, max, step)
yield from range(max, min, -1 * step)
在最小值、最大值和步长上精心选择值(即可整除),
for value in tri_wave(0, 8, 2):
print(value, end=", ")
我只得到一次最小值和最大值,这是我的目标:
...0, 2, 4, 6, 8, 6, 4, 2, 0, 2, 4, 6, 8, 6, 4...
我当时用的是Python3.6
我很好奇是否可以在没有条件和枚举的情况下实现这种三角振荡器。那么,一种选择如下:
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
这背后的想法是取 2 个不同周期的锯齿波,然后从另一个中减去。结果将是值为 {0, magnitude} 的方波。然后我们只需将 {0, magnitude} 分别替换为 {-1, +1} 以获得目标信号的导数值。
让我们看一下 magnitude = 5
的例子:
o = oscillator(5)
[next(o) for _ in range(21)]
这输出 [0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
.
如果允许abs()
,可以简单使用。例如,以下代码给出与上面相同的输出:
[abs(5 - ((x + 5) % 10)) for x in range(21)]