在python中生成具有给定边界的范围元组列表

fav*_*tti 8 python tuples list range

[编辑]我不确定这是否更好的代码审查,如果是这样,请迁移:)谢谢!

所以我们坐在这里,研究半学术问题.

给定a start,stopstep生成范围元组列表,这样

gen_range(100, 140, 10)
Run Code Online (Sandbox Code Playgroud)

会产生

[(100, 110), (110, 120), (120, 130), (130, 140)]
Run Code Online (Sandbox Code Playgroud)

同时,如果事实它应该工作,比如说,迭代500M整数,步长为100而不是永远.

我提出的实现如下:

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)
Run Code Online (Sandbox Code Playgroud)

但我不能不认为它可以以更有效(也是代码长度方式)的方式完成.有什么建议?

[编辑]

有一件事我忘了指出.如果范围边界不等于该步骤,即您有以下情况:

gen_range(100, 143, 10)
Run Code Online (Sandbox Code Playgroud)

由于range()内部原因,上边界应该是143,而不是150,因为这里的一些答案会产生.

Amb*_*ber 6

一个很短的方法:

ranges = [(n, min(n+step, stop)) for n in xrange(start, stop, step)]
Run Code Online (Sandbox Code Playgroud)

更详细的方法:

也许通过发电机?

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
Run Code Online (Sandbox Code Playgroud)

调用此函数将为您提供一个生成器对象,该对象将按顺序生成每个元组。您可以这样使用它:

for block in gen_range(100000000,600000000,100):
    print block
Run Code Online (Sandbox Code Playgroud)

会输出...

(100000000,100000100)
(100000100,100000200)
(100000200,100000300)
...
(599999900,600000000)
Run Code Online (Sandbox Code Playgroud)

如果您始终可以确定生成器表达式stop-start是的偶数倍,则可以使用生成器表达式更简单地执行此操作step

ranges = ((n, n+step) for n in xrange(start, stop, step))

# Usage
for block in ranges:
    print block
Run Code Online (Sandbox Code Playgroud)

还要注意,如果要将生成器转换为列表,并将结果的全部保存在内存中,则可以将其传递给list()

all_ranges = list(gen_range(100000000,600000000,100))
Run Code Online (Sandbox Code Playgroud)

  • 但是,请参阅我刚刚编辑的代码长度优化版本。至少是很漂亮的。 (4认同)