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

2024-05-29 05:08:57 发布

您现在位置:Python中文网/ 问答频道 /正文

[编辑]我不确定这是否更适合codereview,如果是,请迁移:)谢谢!

所以我们坐在这里,研究一个半学术性的问题。

给定一个startstopstep,生成一个范围元组列表,以便

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)

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


Tags: 编辑列表stepbatchrangestartlist事实
3条回答

像这样的:

In [48]: it=iter(xrange(100,200,10))

In [49]: it1=iter(xrange(110,210,10))

In [50]: [(next(it),next(it1)) for _ in range(10)]
Out[50]: 
[(100, 110),
 (110, 120),
 (120, 130),
 (130, 140),
 (140, 150),
 (150, 160),
 (160, 170),
 (170, 180),
 (180, 190),
 (190, 200)]

或者使用zip()

In [55]: it=iter(xrange(100,200,10))

In [56]: it1=iter(xrange(110,210,10))

In [57]: [(x,y) for x,y in zip(it,it1)]
Out[57]: 
[(100, 110),
 (110, 120),
 (120, 130),
 (130, 140),
 (140, 150),
 (150, 160),
 (160, 170),
 (170, 180),
 (180, 190),
 (190, 200)]

很短的路:

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-startstep的偶数倍,则可以更简单地使用生成器表达式:

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))

我不确定我是否正确理解了这个问题,但这可以通过简单的列表理解来完成:

start = 100
stop = 140
step = 10
[ range(s,s+step+1,step) for s in range(start,stop,step)]

如果一次只需要遍历一个列表元素,我强烈建议您使用生成器理解:

res = ( range(s,s+step+1,step) for s in range(start,stop,step))

您可以在一个循环中对其进行迭代:

for range_piece in res:
    do_something with it

相关问题 更多 >

    热门问题