我需要在两个值之间循环,有时第一个值小于第二个值,有时第一个值大于第二个值(我正在处理网格中的两个单元格,第一个单元格可以在第二个单元格左侧或右侧)。
使用Python,我可以指定for循环是要递减还是递增其值,但结果会像这样:
step = 1
if y < x:
step = -1
for n in range(x, y, step):
pass
有没有更符合 Python 语言特色的方法来获取这个结果呢?
step=-1
并不等同于从较大值到较小值的范围!>>> range(3, 7, 1)
[3, 4, 5, 6]
>>> range(7, 3, -1)
[7, 6, 5, 4]
>>> x, y = 7, 3
>>> range(x, y, x < y or -1)
[7, 6, 5, 4]
>>> 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)))
(虽然我认为这不太可读)。
x,y
对进行排序(每种方法使用相同的对):
x,y = sorted((x,y))
-> 1000个对大约需要305µsx,y = min(x,y),max(x,y)
-> 1000个对大约需要235µsx,y = (x,y) if x < y else (y,x)
-> 1000个对大约需要75µsrange(*((x, y) if x < y else (y, x)))
代替调用 sorted()
函数。 - martineausorted()
绝对是最易读的,而且在99.9%的情况下都很好用。正是我在C语言背景下思考,才会想到使用三元表达式来避免调用函数来排序两个项目。 - martineau我猜你可以像这样做:
for n in xrange(min(x,y), max(x,y)):
你的方式已经非常符合Pythonic的写法了 ;)
编辑:@wap26建议的更简洁的方式:
for n in xrange(*sorted((x,y))):
xrange(*sorted((x,y)))
- wap26这并不会对您的代码做出太多不同,但您可以使用它来计算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]
for n in range(x, y, -1 if y < x else 1):
。这本质上与你的代码相同。 - Markus Meskanen