沿任一方向循环遍历间隔
Looping through an interval in either direction
假设您想遍历两个边界 a
和 b
(含)之间的所有整数,但事先不知道 a
与 [=15= 相比如何].预期行为:
def run(a, b):
if a < b:
for i in range(a, b + 1):
print i,
elif a > b:
for i in range(a, b - 1, -1):
print i,
else:
print a
print
run(3, 6)
run(6, 3)
run(5, 5)
结果:
3 4 5 6
6 5 4 3
5
有没有更优雅的方案?下面比较简洁,但是当a == b
:
时失败
def run(a, b):
for i in range(a, b + cmp(b, a), cmp(b, a)):
print i,
print
run(3, 6)
run(6, 3)
run(5, 5)
结果:
3 4 5 6
6 5 4 3
(...)
ValueError: range() step argument must not be zero
range(min((a,b)), max((a,b))+1)
这适用于所有情况:
def run(a, b):
"""Iterate from a to b (inclusive)."""
step = -1 if b < a else 1
for x in xrange(a, b + step, step):
yield x
让我得出这个公式的洞察力是 step
和对 b
的调整在你的两个案例中是相同的;一旦你有了包容性的结局,你就不需要特例 a == b
。请注意,我将其编写为生成器,因此它不只是 print
结果,当您需要将其与其他代码集成时,它会更有用:
>>> list(run(3, 6))
[3, 4, 5, 6]
>>> list(run(6, 3))
[6, 5, 4, 3]
>>> list(run(5, 5))
[5]
在 Python 3.3+ 中使用生成器委托(参见 PEP-380),这变得更加整洁:
def run(a, b):
"""Iterate from a to b (inclusive)."""
step = -1 if b < a else 1
yield from range(a, b + step, step)
你差一点就得到了:
def run(a, b):
for i in range(a, b + (cmp(b, a) or 1), cmp(b, a) or 1):
print i,
print
工作得很好......当 cmp(b, a)
评估为 0
(当它们相等时),它默认为 1
,尽管我肯定认为 Jon 的回答更优雅,你走在正确的轨道上!在进行这样的比较时,我广泛使用 python 的逻辑 or
:
(func() or default)
对于 returns 要覆盖的零的任何函数都非常有用。 Python 将其计算为 False or True
和 returns default
.
假设您想遍历两个边界 a
和 b
(含)之间的所有整数,但事先不知道 a
与 [=15= 相比如何].预期行为:
def run(a, b):
if a < b:
for i in range(a, b + 1):
print i,
elif a > b:
for i in range(a, b - 1, -1):
print i,
else:
print a
print
run(3, 6)
run(6, 3)
run(5, 5)
结果:
3 4 5 6
6 5 4 3
5
有没有更优雅的方案?下面比较简洁,但是当a == b
:
def run(a, b):
for i in range(a, b + cmp(b, a), cmp(b, a)):
print i,
print
run(3, 6)
run(6, 3)
run(5, 5)
结果:
3 4 5 6
6 5 4 3
(...)
ValueError: range() step argument must not be zero
range(min((a,b)), max((a,b))+1)
这适用于所有情况:
def run(a, b):
"""Iterate from a to b (inclusive)."""
step = -1 if b < a else 1
for x in xrange(a, b + step, step):
yield x
让我得出这个公式的洞察力是 step
和对 b
的调整在你的两个案例中是相同的;一旦你有了包容性的结局,你就不需要特例 a == b
。请注意,我将其编写为生成器,因此它不只是 print
结果,当您需要将其与其他代码集成时,它会更有用:
>>> list(run(3, 6))
[3, 4, 5, 6]
>>> list(run(6, 3))
[6, 5, 4, 3]
>>> list(run(5, 5))
[5]
在 Python 3.3+ 中使用生成器委托(参见 PEP-380),这变得更加整洁:
def run(a, b):
"""Iterate from a to b (inclusive)."""
step = -1 if b < a else 1
yield from range(a, b + step, step)
你差一点就得到了:
def run(a, b):
for i in range(a, b + (cmp(b, a) or 1), cmp(b, a) or 1):
print i,
print
工作得很好......当 cmp(b, a)
评估为 0
(当它们相等时),它默认为 1
,尽管我肯定认为 Jon 的回答更优雅,你走在正确的轨道上!在进行这样的比较时,我广泛使用 python 的逻辑 or
:
(func() or default)
对于 returns 要覆盖的零的任何函数都非常有用。 Python 将其计算为 False or True
和 returns default
.