你真的不应该这样做,因为列表推导不应该有任何副作用(列表推导返回一个列表,仅此而已)。很明显,绘制进度条是副作用。
此外,如果你有一个进度条,我想这个过程会相当慢:列表理解不会(可能)比常规循环执行得更好。
所以:不要这样做。
您已被警告...但既然您提出了这个问题,让我们尝试一个简单的列表理解:
>>> L = [sum(range(i**3)) for i in range(100)]
>>> L
[0, 0, 28, 351, 2016, ..., 416485546128, 442920719836, 470739589551]
如果我将其转换为常规循环,我可以使用 progress 模块:
from progress.bar import ChargingBar
L = []
bar = ChargingBar('Loading...')
for i in range(100):
L.append(sum(range(i**3)))
bar.next()
bar.finish()
print(L)
输出:
Loading... ████████████████████████████████ 100%
[0, 0, 28, 351, 2016, ..., 416485546128, 442920719836, 470739589551]
现在,我用一个小技巧来实现我的列表理解:
from progress.bar import ChargingBar
bar = ChargingBar('Loading...')
L = [sum(range(i**3)) for i in range(100) if not bar.next()]
bar.finish()
print(L)
输出:
Loading... ████████████████████████████████ 100%
[0, 0, 28, 351, 2016, ..., 416485546128, 442920719836, 470739589551]
诀窍很容易理解:bar.next() 在每次迭代(条形进度)上进行评估并返回 None。在布尔上下文中,None 是 False:
>>> bool(None)
False
因此,not bar.next() 是 True 并且该列表未被过滤([... for ... if True] 与 [... for ...] 相同)。
再说一遍,不要这样做。