在任一方向上循环一段时间

时间:2016-06-26 08:32:10

标签: python loops intervals

假设您想要遍历两个边界ab(包括)之间的所有整数,但事先并不知道ab的比较。预期的行为:

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

3 个答案:

答案 0 :(得分:7)

这适用于所有情况:

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)

答案 1 :(得分:2)

你几乎得到了它自己:

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&#39;回答更优雅,你走在正确的轨道上!在进行这样的比较时,我大量使用了python的逻辑or

(func() or default)对于任何返回要覆盖的零的函数非常有用。 Python将其评估为False or True并返回default

答案 2 :(得分:-3)

range(min((a,b)), max((a,b))+1)