Функция Range() в Python 3 — работа с циклами и float

1784

Что такое функция Python’s range()?

Если вы опытный разработчик Python, или даже новичок, вы, несомненно, слышала о функции Python range(). Но что же она делает? В двух словах, она генерирует список чисел, который обычно используется для работы с циклом for. Существует много вариантов использования. Зачастую, ее используют, когда нужно выполнить действие X раз, где вы можете использовать индекс. В других случаях вам, возможно, понадобится сделать итерацию по списку (или по другому итерируемому объекту), имея доступ к индексу.

Функция range() имеет небольшие отличия в работе на версии Python 2.x и 3.x , тем не менее у них остается одинаковая концепция. К этому вопросу мы доберемся немного позже.

Параметры Python’s range()

Функция range() принимает два параметра, например:

range(stop)
  • stop:
    Количество целых чисел для генерации, начиная с нуля. например.
    range(3) == [0, 1, 2].
range([start], stop[, step])
  • start: число начала последовательности.
  • stop: генерирует число до данного числа, но не включая его.
  • step: разница между каждым числом из последовательности

Обратите внимание,что:

  • Все параметры должны быть целыми числами:
  • Каждый из параметров может быть как положительным, так и отрицательным.
  • range() (и Python в целом) основана на индексе 0, означая, что список индексов начинается с 0, а не 1, например. Синтаксис, предоставляющий доступ к первому элементу в списке — mylist[0]. Поэтому, последнее целое число, сгенерированное функцией range() зависит от stop, но не будет включать его. Например, range(0, 5) генерирует целые числа 0, 1, 2, 3, 4, но не включая 5.

Примеры функции Python range()

Простое применение

>>> # 5 чисел начиная с 0
>>> for i in range(5):
... print(i)
...
0
1
2
3
4
>>> # числа с 3 до 6 (не включая его)
>>> for i in range(3, 6):
... print(i)
...
3
4
5
>>> # числа с 4 до 10(не включая его) с шагом 2
>>> for i in range(4, 10, 2):
... print(i)
...
4
6
8
>>> # числа с 0 до -10(не включая его) с шагом -2
>>> for i in range(0, -10, -2):
... print(i)
...
0
-2
-4
-6
-8

Итерация по спискам

>>> my_list = ['one', 'two', 'three', 'four', 'five']
>>> my_list_len = len(my_list)
>>> for i in range(0, my_list_len):
... print(my_list[i])
...
one
two
three
four
five

На примере песни “99 Bottles of Beer on the Wall…”
Со следующим кодом:

for i in range(99, 0, -1):
	if i == 1:
		print('1 bottle of beer on the wall, 1 bottle of beer!')
		print('So take it down, pass it around, no more bottles of beer on the wall!')
	elif i == 2:
		print('2 more bottles of beer on the wall, 2 more bottles of beer!')
		print('So take one down, pass it around, 1 more bottle of beer on the wall!')
	else:
		print('{0} bottles of beer on the wall, {0} bottles of beer!'.format(i))
		print('So take it down, pass it around, {0} more bottles of beer on the wall!'.format(i - 1))

Мы получаем следующий результат:

99 bottles of beer on the wall, 99 bottles of beer!
So take one down, pass it around, 98 more bottles of beer on the wall!
98 bottles of beer on the wall, 98 bottles of beer!
So take one down, pass it around, 97 more bottles of beer on the wall!
97 bottles of beer on the wall, 97 bottles of beer!
So take one down, pass it around, 96 more bottles of beer on the wall!
...
3 bottles of beer on the wall, 3 bottles of beer!
So take one down, pass it around, 2 more bottles of beer on the wall!
2 more bottles of beer on the wall, 2 more bottles of beer!
So take one down, pass it around, 1 more bottle of beer on the wall!
1 bottle of beer on the wall, 1 bottle of beer!
So take it down, pass it around, no more bottles of beer on the wall!

Прекрасно! Наконец-то вы видите настоящую силу Python. Если вы еще немного в замешательстве, рекомендую прочитать статью 99 бутылок пива (Википедия).

Python range() против функций xrange()

Вы должно быть слышали о функции, известной как xrange(). Эта функция представлена в Python 2.x, и была переименована в range() в Python 3.x. Так в чем же разница? В Python 2.x range() создавала список, а xrange() возвращала итератор — объект последовательности. Мы можем увидеть это в следующем примере:

Тест на знание python

Что выведет этот код?
Функция Range() в Python 3 — работа с циклами и float
Какая функция удаляет объект из списка?
Какое значение вернет код colors[2] ?
Функция Range() в Python 3 — работа с циклами и float
Какой будет результат выполнения этого кода?
Функция Range() в Python 3 — работа с циклами и float
Что выведет этот код?
Функция Range() в Python 3 — работа с циклами и float
# Python 3.x
>>>  range(1)
range(0,  1)
>>>  type(range(1))
<class  'range'>
# Python 2.x
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>

В Python 3.x. у функции range() есть свой собственный тип. Говоря языком простых терминов, если вы хотите воспользоваться range() в цикле for, вы сделаете это с легкостью. Однако вы не можете использовать его как объект списка. Например, вы не можете разбить на срезы тип range.
Когда вы используете итератор, каждый цикл оператора for выдает мгновенно последующий номер на лету. В то время как исходная функция range() производит все числа мгновенно, прежде чем цикл for начнет выполняться. Проблема с исходной функцией range() (в Python 2.x) заключалась в том, что она требовала очень большой объем памяти при создании большого количества чисел. Однако в нем, как правило, можно работать быстрее с небольшим количеством чисел. Обратите внимание, что в Python 3.x вы все равно можете создать список, передав генератор, возвращенный функции list(). Следующим образом:

>>> list_of_ints = list(range(3))
>>> list_of_ints
[0, 1, 2]

Чтобы увидеть разницу в скорости действия в функции range() и xrange(), посмотрите эту статью (english).

Использование float с функцией Python range()

К сожалению, функция range() не поддерживает тип float. Тем не менее, не спешите расстраиваться! Мы можем легко использовать его с помощью данной функции. Есть несколько способов сделать это, вот один из них.

>>> # все аргументы обязательны
>>> # мы не очень довольны, тем как это реализовано.
>>> def frange(start, stop, step):
... 	i = start
... 	while i < stop:
... 		yield i
... 		i += step
...
>>> for i in frange(0.5, 1.0, 0.1):
... 	print(i)
...
0.5
0.6
0.7
0.8
0.9
1.0