В чем разница между "диапазоном (0,2)" и "списком (диапазон (0,2))"?
Вам нужно понять разницу между range(0,2)
и list(range(0,2))
, используя python2.7
Оба возвращают список, так что же такое разница?
Ответы
Ответ 1
В Python 3.x,
range(0,3)
возвращает класс неизменяемых итерируемых объектов, который позволяет вам перебирать их, он не создает списки и не сохраняет все элементы в диапазоне в памяти, вместо этого они создают элементы "на лету" (как вы повторяете их), тогда как list(range(0,3))
создает список (путем повторения всех элементов и добавления в список внутри).
Пример -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
В идеале, если вы хотите только перебирать этот диапазон значений, range(0,3)
будет быстрее, чем (list(range(0,3))
, потому что у последнего есть накладные расходы на создание списка, прежде чем вы начнете его повторять.
В Python 2.x, range(0,3)
создает список, вместо этого у нас также была функция xrange()
, которая имеет аналогичное поведение функции range()
из Python 3.x(xrange был переименован в диапазон в Python 3.x )
Для Python 3.5, из документации -
Объекты Range реализуют сборники .abc.Sequence ABC и предоставляют такие функции, как тесты сдерживания, поиск индекса элемента, нарезка и поддержка отрицательных индексов
Итак, вы можете делать такие вещи, как -
>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
И все это операции с постоянным временем, как видно из этого теста -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
Ответ 2
Это зависит от того, какую версию Python вы используете.
В Python 2.x, range()
возвращает список, поэтому они эквивалентны.
В Python 3.x range()
возвращает неизменный тип последовательности, вам нужно list(range(0,2))
, чтобы получить список.
Ответ 3
Обе команды возвращают список в Python2.x. Но в диапазоне Python3.x есть неизменная последовательность и не возвращает список. Он используется для циклов объявлений итераций
Ответ 4
В python3.x диапазон имеет свой собственный тип
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>
Итак, если вы хотите использовать range() в цикле for, то это прекрасно. Однако вы не можете использовать его purely
как объект списка. Вам нужно преобразовать его в список, чтобы сделать это.
Пример Python2:
>>> L = range(10)
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Пример Python3:
>>> L = range(10)
>>> L[::-1]
range(9, -1, -1)
Ответ 5
В основном разница заключается в том, что range(0, 2)
является функцией генератора, а list(range(0, 2))
является фактическим списком.
Функция генератора используется в циклах. Например, функция генератора файла будет читать очень большой файл по строкам.
def gen():
for line in open("hugefile.csv", "r"):
yield line #Gives back the line every time it is read, but forgets that line after
for line in gen():
print(line)
Это будет печатать каждую строку без перегрузки ОЗУ компьютера, потому что вы только читаете один за другим в обеих функциях. Однако, если мы сделаем что-то вроде
def readEntireFile():
return [line for line in open("hugefile.csv", "r")] #Python has lazy ways of making lists, this is the same as returning a list with all the lines in the file
for line in readEntireFile():
print(line)
Вторая часть выглядит одинаково, но это не так. Первоначально мы перебирали каждую строку в файле и переходим к следующей строке, когда мы закончили с ней. Здесь Python имеет список ВСЕХ строк:/, представьте себе, что с 10-гигабайтным файлом! Ваш код сработает.
Теперь вернемся к диапазону() и списку (range())
Выполнение for x in range(0, 6):
заставляет нас перейти к следующему номеру диапазона и полностью забыть о предыдущей (винтовая грамматика).
Однако при выполнении for x in list(range(0, 6)):
сохраняется весь список чисел в памяти и тот же, что и при выполнении
numlist = [x for x in range(6)]
for x in numlist:
print(x)
Когда вам нужен весь список данных в вашем коде, используйте метод списка. Но когда вам нужна только одна часть данных за один раз (самый простой пример - копирование файла в кусках), используйте функцию генератора для экономии места. Вы можете копировать каждые 1 миллион строк файла, используя только 54 мб (при условии, что у вас нет безумно длинной строки). Однако, если у нас есть крошечный файл размером 2 КБ, мы можем просто скопировать эту вещь без генератора. Это не стоит времени и в этом случае медленнее.