python 在一个不带列表解析的range(y)循环中的3个模式

amrnrhlw  于 2022-11-21  发布在  Python
关注(0)|答案(2)|浏览(110)

我不想分别使用3个循环,而只想使用一个循环,这样可以加快代码的速度。
range(0,150)有3种不同的模式,每个循环增加3个:

0,3,6,9...
1,4,7,10...
2,5,8,11....

我的代码:

fromlist = [1,2,3,4,5]
req1list = ['z','t','y']
req2list = [21,39,52]
req3list = [100,200,300]

for i in range(0,150,3):
    req1list.append(fromlist[i])
for j in range(1,150,3):
    req2list.append(fromlist[j])
for x in range(2,151,3):
    req3list.append(fromlist[x])

注意,列表已经创建,并且文件中有数据。因此,我认为列表理解是不可能的。
另一个注意事项:请忽略列表长度,在我的文件中,列表要长得多,并且不会在[]中导致错误。
有没有什么方法可以将这3个循环合并为一个,并加快代码的速度?

rdlzhqv9

rdlzhqv91#

如果你调用extend而不是append,你会得到更快的结果,而不是尝试在每次迭代中(在一个循环中)执行三次追加。你也可以使用分片来避免理解:

req1list.extend(fromlist[::3])
req2list.extend(fromlist[1::3])
req3list.extend(fromlist[2::3])

如果在150处停止很重要,则将其添加到切片操作中:

req1list.extend(fromlist[:150:3])
# ...etc
vom3gejh

vom3gejh2#

另一种稍微不同的方法是使用itertools文档中定义的grouper函数。

def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
    args = [iter(iterable)] * n
    if incomplete == 'fill':
        return zip_longest(*args, fillvalue=fillvalue)
    if incomplete == 'strict':
        return zip(*args, strict=True)
    if incomplete == 'ignore':
        return zip(*args)
    else:
        raise ValueError('Expected fill, strict, or ignore')

有了这个,你就可以写

for x, y, z in grouper(fromlist, 3):
    req1list.append(x)
    req2list.append(y)
    req3list.append(z)

(You可以将文档中grouper的定义复制到您自己的代码中,或者使用第三方more-itertools包(其中包含该定义以及许多用于处理迭代器的有用函数)。

相关问题