使用range()而不是例如列表可能很方便,但如果将range()分配给变量,则pylint会发出警告。 (范围内建而不迭代)
范围对象是列表(具有长度,可以随机访问,可迭代等),因此在某些情况下此代码是错误的吗?
from typing import *
def fn(a: Sequence[int]) -> None:
for x in a:
print(x)
r = range(10, 100)
fn(r)
编辑(添加):
这样做的动机是传递范围,而不是在整个地方传递(开始,结束)对。
答案 0 :(得分:0)
我认为pylint不能正确证明该警告。
official文档的理由
(在Python 3中返回迭代器)
适用于迭代器(例如map),但不适用于范围。
要轻松查看iterator
对象和non-iterator
对象之间的区别,可以执行以下几行
r = range(5)
print(list(r)) # [0, 1, 2, 3, 4]
print(list(r)) # [0, 1, 2, 3, 4]
m = map(int, '01234')
print(list(m)) # [0, 1, 2, 3, 4]
print(list(m)) # []
iterator
消耗了元素。
但是,我认为这不是一个好习惯,因为您可能会倾向于将其用作列表,在某些情况下可能会变慢。
让我们举两个例子
r = range(500000)
l = list(r)
%%time
for i in range(200):
for k in r:
pass
# 6.7 sec on my computer
%%time
for i in range(200):
for k in l:
pass
# 4.5 sec on my computer
主要区别在于list
被加载到内存中,迭代速度更快。
编辑:如果您正在寻找速度,则可能要使用列表,否则也许应该使用范围。
我今天早些时候在pylint上打开了一个issue,如果值得进行拉取请求,我稍后会处理