我必须在两个值之间循环,有时第一个值小于第二个值,有时第一个值大于第二个值(我在网格中的两个单元格上工作,第一个单元格可以是在第二个左侧或反之亦然。)
使用python我可以指定for循环是否必须减少或增加其值,但结果是这样的:
step = 1
if y<x:
step = -1
for n in range(x,y,step):
pass
有更多的pythonic来获得这个吗?我使用python 2.7但是转到python 3它不会是一个很大的问题。
答案 0 :(得分:9)
请注意,使用step=-1
不与从较小值到较大值的范围相同!
>>> range(3, 7, 1)
[3, 4, 5, 6]
>>> range(7, 3, -1)
[7, 6, 5, 4]
第一个是3到6,后者是4到7。
如果仍然是你想要的,另一种方法是使用or
:
>>> x, y = 7, 3
>>> range(x, y, x < y or -1)
[7, 6, 5, 4]
如果要包含较低和较高的索引,则必须偏移to
索引:
>>> step = +1 if x < y else -1 # or use that 'or' expression
>>> range(x, y + step, step)
[7, 6, 5, 4, 3]
否则,您可以先使用min
和max
或sorted
对值进行排序:
>>> x, y = sorted((x, y))
>>> range(x, y)
[3, 4, 5, 6]
或者在一行中:range(*sorted((x, y)))
(虽然我认为这不是非常易读)
我做了一些时序分析,订购了1000个随机x, y
对(每种方法都有相同的对):
x, y = sorted((x, y))
- &gt; 1000对~305μsx, y = min(x, y), max(x, y)
- &gt; 1000对〜235μsx, y = (x, y) if x < y else (y, x)
- &gt; 1000对~75μs因此三元运算符是最快的,但在大多数情况下,与其余代码(创建范围等)相比,它可能并不重要。
答案 1 :(得分:4)
我想你可以这样做:
2015-08-10T21:00:00.090Z
你的方式已经非常pythonic;)
编辑:@ wap26建议的缩短方式:
for n in xrange(min(x,y), max(x,y)):
答案 2 :(得分:1)
与您的代码没有太大区别,但您可以使用它来计算step
range(x,y,(y-x)/abs(x-y))
例如:
In [10]: x,y = 5,10
In [11]: range(x,y,(y-x)/abs(x-y))
Out[11]: [5, 6, 7, 8, 9]
In [12]: x,y = 10,5
In [13]: range(x,y,(y-x)/abs(x-y))
Out[13]: [10, 9, 8, 7, 6]