Перейти к содержимому

Как заменить range в питоне

  • автор:

Питонистический подход к циклам for: range() и enumerate()

Автор заметки, перевод которой мы сегодня публикуем, хочет рассказать о некоторых особенностях использования циклов for в Python.

Цикл for — это один из краеугольных камней программирования. С этими циклами будущие программисты знакомятся в самом начале учёбы и, после первого знакомства, пользуются ими постоянно.

Если вы занялись разработкой на Python, имея опыт работы с другим популярным языком программирования, вроде PHP или JavaScript, то вам знакома методика применения переменной-счётчика, хранящей, например, индекс текущего элемента массива, обрабатываемого в цикле. Вот пример работы с циклом, написанный на JavaScript:

let scores = [54,67,48,99,27]; for(const i=0; i < scores.length; i++) < console.log(i, scores[i]); >/* 0 54 1 67 2 48 3 99 4 27 */

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

В предыдущем примере переменная i не имеет какого-то явного отношения к массиву scores . Она всего лишь хранит некое число, которое увеличивается на 1 в каждой итерации цикла, и которое, как оказывается, подходит для последовательного обращения к элементам массива по их индексам.

Старый (неудачный) способ работы с массивами

В Python нет традиционных циклов for , подобных тому, что показан выше. Правда, если вы похожи на меня, то первым вашим желанием при освоении Python станет поиск способа создания цикла, с которым вам привычно и удобно работать.

В результате вы можете обнаружить функцию range() и написать на Python нечто подобное следующему:

scores = [54,67,48,99,27] for i in range(len(scores)): print(i, scores[i]) """ 0 54 1 67 2 48 3 99 4 27 """

Проблема этого цикла заключается в том, что он не очень хорошо соответствует идеологии Python. В нём мы не перебираем список, а, вместо этого, используем вспомогательную переменную i для обращения к элементам списка.

На самом деле, даже в JavaScript существуют методы, позволяющие перебирать массивы, так сказать, без посредников. Речь идёт о циклах forEach и for of .

Использование функции enumerate()

Если вам нужно адекватным образом отслеживать «индекс элемента» в for -цикле Python, то для этого может подойти функция enumerate() , которая позволяет «пересчитать» итерируемый объект. Её можно использовать не только для обработки списков, но и для работы с другими типами данных — со строками, кортежами, словарями.

Эта функция принимает два аргумента: итерируемый объект и необязательное начальное значение счётчика.

Если начальное значение счётчика enumerate() не передаётся — оно, по умолчанию, устанавливается в 0 . Функция создаёт объект, генерирующий кортежи, состоящие из индекса элемента и самого этого элемента.

scores = [54,67,48,99,27] for i, score in enumerate(scores): print(i, score)

Такой код получился гораздо чище кода из предыдущего примера. Мы ушли от работы со списком индексов, мы перебираем сами значения, получая к ним прямой доступ в цикле for, и видим значения, с которыми работаем, в объявлении цикла.

Вот одна приятная возможность, которая понравится тем, кому нужно выводить нумерованные списки так, чтобы номер первого элемента был бы не 0 , в соответствии с его индексом, а 1 . Обычно для того, чтобы это сделать, приходится менять выводимый номер элемента. Например — так: i + 1 . При использовании же функции enumerate() достаточно передать ей, в качестве второго аргумента, то число, с которого нужно начинать нумерацию. В нашем случае — 1 :

scores = [54,67,48,99,27] for i, score in enumerate(scores, 1): print(i, score) """ 1 54 2 67 3 48 4 99 5 27 """

Итоги

Надеюсь, этот небольшой рассказ о циклах for в Python позволил вам узнать что-то новое об этом языке.

Уважаемые читатели! Знаете ли вы ещё какие-нибудь способы применения функции enumerate() ? Кажутся ли вам циклы, построенные с использованием enumerate() , более читабельными, чем циклы, созданные с использованием range(len()) ?

Python цикл for — for i in range

Циклы являются одной из основных управляющих конструкций в любом языке программирования, и Python не является исключением.

В этой статье мы рассмотрим несколько примеров использования циклов for с функцией range() в Python.

Циклы for в Python

Циклы for повторяют определённый код для некоторого набора значений.

Из документации Python можно узнать, что в нем циклы for работают несколько иначе, чем в таких языках, как JavaScript или C.

Цикл for присваивает итерируемой переменной каждое значение из предоставленного списка, массива или строки и повторяет код в теле цикла for для каждого установленного таким образом значения переменной-итератора.

В приведенном ниже примере мы используем цикл for для вывода каждого числа в нашем массиве.

Описание функции range с примерами для Python 3

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

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

Параметры range: star, stop, шаг

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

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

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

Простое применение с циклом for:

 
>>> # 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 = ['один', 'два', 'три', 'четыре', 'пять'] >>> my_list_len = len(my_list) >>> for i in range(0, my_list_len): print(my_list[i]) один два три четыре пять

В качестве параметра stop мы передали длину списка (5).

Range полезна в итерации с условиями. Рассмотрим примере песни “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(' bottles of beer on the wall, bottles of beer!'.format(i)) print('So take it down, pass it around, 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 бутылок пива (Википедия).

range против функций xrange в python

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

# Python 3.x >>> range(1) range(0, 1) >>> type(range(1)) range'> # Python 2.x >>> range(1) [0] >>> type(range(1)) list'>

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

Когда вы используете итератор, каждый цикл оператора for выдает мгновенно последующий номер на лету. В то время как исходная функция range() производит все числа мгновенно, прежде чем цикл for начнет выполняться.

Проблема с исходной функцией range() (в Python 2.x) заключалась в том, что она требовала очень большой объем памяти при создании большого количества чисел. Однако в нем, как правило, можно работать быстрее с небольшим количеством чисел.

Обратите внимание, что в Python 3.x вы все равно можете создать список, передав генератор, возвращенный функции list() . Следующим образом:

Оператор цикла for. Функция range()

На предыдущих занятиях мы с вами познакомились с оператором цикла while, а также вспомогательными операторами break, continue и else. На этом занятии вы узнаете о втором операторе цикла for, который довольно часто используется в Python.

Он имеет следующий синтаксис:

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

Как всегда, постичь магию работу этого оператора лучше всего на конкретных примерах. Пусть у нас имеется список:

d = [1, 2, 3, 4, 5]

И мы хотим перебрать все его элементы. Через оператор цикла for сделать это можно, следующим образом:

for x in d: print(x)

Или, вместо списка, можно взять строку:

for x in "python": print(x)

Тогда переменная x на каждой итерации будет ссылаться на очередной символ этой строки.

Но давайте посмотрим, как все это работает в деталях. Вернемся к примеру со списком. На первой итерации переменная x будет ссылаться на первый элемент со значением 1. Соответственно, функция print() выводит это значение в консоль. На следующей итерации переменная x ссылается уже на второй элемент и print() выводит значение 2. И так до тех пор, пока не будет достигнут конец списка.

В этой демонстрации ключевое, что переменная x ссылается на элемент списка. То есть, если мы захотим изменить значение в списке, используя переменную x, например, вот так:

for x in [1, 2, 3, 4, 5]: x = 0

то ничего не получится. Здесь x просто будет ссылаться на другой объект со значением 0, но элементы списка это никак не затронет. То есть, в такой реализации оператора цикла for мы можем лишь перебирать значения элементов и что-то с ними делать, например, вычислять их произведение:

d = [5, 2, 4, 3, 1] p = 1 for x in d: p *= x print(p)

А как тогда менять значения элементов в списке с помощью for? Для этого к элементам списка нужно обращаться по индексу. То есть, цикл должен перебирать не элементы списка, а его индексы:

d = [5, 2, 4, 3, 1] for i in [0, 1, 2, 3, 4]: d[i] = 0 print(d)

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

Однако описывать индексы через еще один список, далеко не лучшая практика. Для подобных целей в Python существует специальная функция range(), которая генерирует арифметическую последовательность чисел с параметрами:

range(start, stop, step)

Например, для генерации последовательности от 0 до 4, функцию range() можно записать в виде:

range(5) range(0, 5) range(0,5,1)

То есть, последнее значение 5 не включается в диапазон. Чтобы увидеть сгенерированные числа, преобразуем их последовательность в список с помощью известной нам функции list():

list(range(5)) list(range(0, 5)) list(range(0, 5, 1))

Если же мы запишем:

list(range(0))

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

То же самое произойдет при указании любого отрицательного значения, например:

list(range(-5)) list(range(0, -5))

Но как нам тогда формировать последовательность отрицательных значений? Очень просто, в качестве стартового значения нужно указать число меньше конечного значения:

list(range(-10, -5))
list(range(-10, -5, 2))

Но если указать отрицательный шаг:

list(range(-10, -5, -2))

то снова увидим пустой список. Я, думаю, вы догадались почему? Теперь, мы начинаем двигаться от -10 в меньшую сторону и значение -5 становится недостижимым. В этом случае функция range() не выдает никаких значений. Чтобы поправить ситуацию, в качестве конечного значения нужно записать число меньше -10, например, -20:

list(range(-10, -20, -2))

Вот так генерируются последовательности в обратном порядке. То же самое можно проделать и в положительной области:

list(range(5, 0, -1))

Обратите внимание, мы начинаем с 5 и заканчиваем 1. Здесь конечное значение 0 не включается в диапазон. Если нам нужно дойти до нуля, то в данном случае следует указать -1 в качестве конечного значения:

list(range(5, -1, -1))

Вот это всегда следует помнить при работе с функцией range() – конечное значение не включается в диапазон.

Итак, теперь, когда мы с вами узнали, как работает функция range(), перепишем нашу программу с перебором элементов списка по их индексам, следующим образом:

d = [5, 2, 4, 3, 1] for i in range(5): d[i] = 0 print(d)

Здесь нам не нужно функцию range() превращать в список, оператор цикла for умеет перебирать любые итерируемые объекты, а range(), как раз возвращает такой объект, поэтому переменная i будет принимать значения от 0 до 4 включительно и мы видим, что все значения списка стали равны нулю.

И последний штрих в этой программе. Число 5 лучше заменить вызовом функции определения длины списка:

len(d)

Тогда получим универсальную программу, работающую со списком любой длины:

for i in range(len(d)): d[i] = 0

В заключение этого занятия приведу еще один пример использования цикла for для вычисления суммы ряда:

S = 1/2 + 1/3 + 1/4 + … + 1/1000

Программу можно реализовать, следующим образом:

S = 0 for i in range(2, 1001): S += 1 / i print(S)

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

Видео по теме

#1. Первое знакомство с Python Установка на компьютер

#2. Варианты исполнения команд. Переходим в PyCharm

#3. Переменные, оператор присваивания, функции type и id

#4. Числовые типы, арифметические операции

#5. Математические функции и работа с модулем math

#6. Функции print() и input(). Преобразование строк в числа int() и float()

#7. Логический тип bool. Операторы сравнения и операторы and, or, not

#8. Введение в строки. Базовые операции над строками

#9. Знакомство с индексами и срезами строк

#10. Основные методы строк

#11. Спецсимволы, экранирование символов, row-строки

#12. Форматирование строк: метод format и F-строки

#13. Списки - операторы и функции работы с ними

#14. Срезы списков и сравнение списков

#15. Основные методы списков

#16. Вложенные списки, многомерные списки

#17. Условный оператор if. Конструкция if-else

#18. Вложенные условия и множественный выбор. Конструкция if-elif-else

#19. Тернарный условный оператор. Вложенное тернарное условие

#20. Оператор цикла while

#21. Операторы циклов break, continue и else

#22. Оператор цикла for. Функция range()

#23. Примеры работы оператора цикла for. Функция enumerate()

#24. Итератор и итерируемые объекты. Функции iter() и next()

#25. Вложенные циклы. Примеры задач с вложенными циклами

#26. Треугольник Паскаля как пример работы вложенных циклов

#27. Генераторы списков (List comprehensions)

#28. Вложенные генераторы списков

#29. Введение в словари (dict). Базовые операции над словарями

#30. Методы словаря, перебор элементов словаря в цикле

#31. Кортежи (tuple) и их методы

#32. Множества (set) и их методы

#33. Операции над множествами, сравнение множеств

#34. Генераторы множеств и генераторы словарей

#35. Функции: первое знакомство, определение def и их вызов

#36. Оператор return в функциях. Функциональное программирование

#37. Алгоритм Евклида для нахождения НОД

#38. Именованные аргументы. Фактические и формальные параметры

#39. Функции с произвольным числом параметров *args и **kwargs

#40. Операторы * и ** для упаковки и распаковки коллекций

#41. Рекурсивные функции

#42. Анонимные (lambda) функции

#43. Области видимости переменных. Ключевые слова global и nonlocal

#44. Замыкания в Python

#45. Введение в декораторы функций

#46. Декораторы с параметрами. Сохранение свойств декорируемых функций

#47. Импорт стандартных модулей. Команды import и from

#48. Импорт собственных модулей

#49. Установка сторонних модулей (pip install). Пакетная установка

#50. Пакеты (package) в Python. Вложенные пакеты

#51. Функция open. Чтение данных из файла

#52. Исключение FileNotFoundError и менеджер контекста (with) для файлов

#53. Запись данных в файл в текстовом и бинарном режимах

#54. Выражения генераторы

#55. Функция-генератор. Оператор yield

#56. Функция map. Примеры ее использования

#57. Функция filter для отбора значений итерируемых объектов

#58. Функция zip. Примеры использования

#59. Сортировка с помощью метода sort и функции sorted

#60. Аргумент key для сортировки коллекций по ключу

#61. Функции isinstance и type для проверки типов данных

#62. Функции all и any. Примеры их использования

#63. Расширенное представление чисел. Системы счисления

#64. Битовые операции И, ИЛИ, НЕ, XOR. Сдвиговые операторы

#65. Модуль random стандартной библиотеки

#66. Аннотация базовыми типами

#67. Аннотации типов коллекций

#68. Аннотации типов на уровне классов

#69. Конструкция match/case. Первое знакомство

#70. Конструкция match/case с кортежами и списками

#71. Конструкция match/case со словарями и множествами

#72. Конструкция match/case. Примеры и особенности использования

© 2024 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://kodirovanie.vyvod-iz-zapoya-na-domu-moskva-snp.ru/