[edit] 我不确定代码审查是否更好,如果是这样,请迁移 :) 谢谢!
所以我们坐在这里,研究一个半学术性的问题。
给定一个start
、stop
和step
,生成一个范围元组列表,这样
gen_range(100, 140, 10)
会产生
[(100, 110), (110, 120), (120, 130), (130, 140)]
此外,考虑到它应该工作的事实,比如说,以 100 的步长迭代 500M 个整数,而不是永远。
我想出的实现如下:
def gen_range(start, stop, step):
llist = range(start, stop+step, step)
batch_list = []
if llist[-1] > stop:
llist[-1] = stop
for a, b in enumerate(llist[:-1]):
batch_list.append((llist[a], llist[a+1]))
print batch_list
gen_range(100000000,600000000,100)
但我一直在想,可以用更高效(代码长度方面)的方式来完成它。有什么建议吗?
[编辑]
有一件事我忘了指出。如果范围边界不等于步长,即您有以下情况:
gen_range(100, 143, 10)
由于 range()
的内部结构,上限应该是 143,而不是 150,因为这里的一些答案会产生。
最佳答案
一个很短的方法:
ranges = [(n, min(n+step, stop)) for n in xrange(start, stop, step)]
更详细的方法:
也许通过发电机?
def gen_range(start, stop, step):
current = start
while current < stop:
next_current = current + step
if next_current < stop:
yield (current, next_current)
else:
yield (current, stop)
current = next_current
调用此函数会为您提供一个生成器对象,它将按顺序生成每个元组。你会像这样使用它:
for block in gen_range(100000000,600000000,100):
print block
这会输出...
(100000000,100000100)
(100000100,100000200)
(100000200,100000300)
...
(599999900,600000000)
如果您始终确定 stop-start
是 step
的偶数倍,则可以使用生成器表达式更简单地执行此操作:
ranges = ((n, n+step) for n in xrange(start, stop, step))
# Usage
for block in ranges:
print block
另请注意,如果您想将生成器转换为列表,将所有结果保存在内存中,只需将其传递给 list()
:
all_ranges = list(gen_range(100000000,600000000,100))
关于python - 在 python 中生成具有给定边界的范围元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14048728/