0

我的目标是将数组分成块,并在for-loop 中循环这些块。在循环时,我还想打印到目前为止我已经循环的数据的百分比(因为实际上我会在每个循环上发出请求,这将导致循环花费很长时间......)

这是代码:

# Function to chunk the data
def chunker(seq, size):
    return (seq[pos:pos + size] for pos in range(0, len(seq), size))

# Init data and chunks
d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chunked = chunker(d, 2)

i = 1
for chunk in chunked:
    print(i)
    print(str((i / len(list(chunked)) * 100)) + '%')
    i += 1
    print('end')

如果您运行此代码,则循环将只运行一次。

但是,如果您注释/删除print(str((i / len(list(chunked)) * 100)) + '%')循环内的语句,那么它将运行 5 次,这是预期的行为。

为什么我的print语句会导致我的循环退出?

4

3 回答 3

4

chunked是一个生成器,而不是一个列表,所以你只能迭代一次。当您调用 时list(chunked),它会消耗生成器的其余部分,因此没有任何内容可供for循环迭代。

此外,len(list(chunked))将比您预期的少 1,因为它不包括列表中迭代的当前元素。

更改chunker为使用列表推导而不是返回生成器。

def chunker(seq, size):
    return [seq[pos:pos + size] for pos in range(0, len(seq), size)]
于 2021-01-08T22:08:17.183 回答
1

你打电话给list(chunked)print(),这会耗尽chunked发电机。for chunk in chunked没有得到任何下一个项目,所以它退出。

于 2021-01-08T22:08:34.533 回答
1

我似乎也有兴趣显示进度条。如果在迭代之前将生成器转换为列表,则可以使用名为tqdm. 确保不要在 for 循环中打印任何内容以防止终端运行 brr。

之后运行此代码$pip install tqdm

from tqdm import tqdm
import time

def chunker(seq, size):
    return list(seq[pos:pos + size] for pos in range(0, len(seq), size))

# Init data and chunks
d = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chunked = chunker(d, 2)
print(chunked)
i = 1

for chunk in tqdm(chunked, desc='Iterating on chunked data'):
    time.sleep(.5)

输出:

[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
Iterating on chunked data: 100%|██████████████████████████| 5/5 [00:02<00:00,  1.96it/s]
于 2021-01-08T22:21:59.667 回答