正确使用range(),为什么pylint抱怨:不迭代时引用了内置的范围

时间:2019-03-05 09:51:04

标签: python python-3.x pylint

使用range()而不是例如列表可能很方便,但如果将range()分配给变量,则pylint会发出警告。 (范围内建而不迭代)

范围对象是列表(具有长度,可以随机访问,可迭代等),因此在某些情况下此代码是错误的吗?

from typing import *

def fn(a: Sequence[int]) -> None:
    for x in a:
        print(x)

r = range(10, 100)

fn(r)

编辑(添加):

这样做的动机是传递范围,而不是在整个地方传递(开始,结束)对。

1 个答案:

答案 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,如果值得进行拉取请求,我稍后会处理