Правильное использование range (), почему pylint жалуется: на встроенный диапазон ссылаются, когда он не повторяется - PullRequest
0 голосов
/ 05 марта 2019

Использование range () вместо, например, списка может быть довольно удобным и точным, но pylint выдает предупреждение, если range () назначен переменной.(range-встроенный-не-итерирующийся)

объекты диапазона имеют список типа (имеют длину, могут быть произвольными, итеративными и т.д.), поэтому существуют ситуации, когда этот код неправильный?

from typing import *

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

r = range(10, 100)

fn(r)

edit (добавлено):

Одной из причин для этого является пропуск диапазона вместо передачи пары (начало, конец) по всему месту

1 Ответ

0 голосов
/ 05 марта 2019

Я думаю, что Pylint неправильно обосновывает это предупреждение.

Обоснование для official doc

(возвращает итератор в Python 3)

подходит для итератора (например, карты), но не для диапазона.

Чтобы легко увидеть разницу между объектом 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 поглотили элементы.

Однако я не думаю, что это хорошая практика, поскольку у вас может возникнуть соблазн использовать его в качестве списка, который может бытьв некоторых случаях медленнее.

давайте возьмем эти 2 примера

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 ранее сегодня, если это стоит запроса на тягуЯ справлюсь позже

...