Enumerate python что это

Функция enumerate, примеры использования

На этом дополнительном занятии я расскажу о функции enumerate. Прежде чем мы углубимся в эту тему, напомню, что в Python для последовательного перебора элементов любого итерируемого объекта используется оператор цикла for. Например:

В момент работы этого цикла переход к следующему элементу осуществляется через объект-итератор. Оператор for автоматически вызывает функцию next() этого итератора и получает текущее значение элемента. И так, пока не дойдет до конца коллекции:

Enumerate python что это. Смотреть фото Enumerate python что это. Смотреть картинку Enumerate python что это. Картинка про Enumerate python что это. Фото Enumerate python что это

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

Если же внутри цикла требуется не только перебирать элементы, но и менять их, то необходимо обращаться к текущему элементу по его индексу, например, так:

Результатом будет измененная коллекция:

Однако, если вместо a[i] использовать x, то упорядоченный список останется без изменений. Этот простой пример наглядно показывает необходимость использования индексов, если нам нужно менять значения элементов. Так вот, чтобы непосредственно в цикле for не только получать ссылку на текущий элемент, но и знать его порядковый индекс, как раз и используется функция enumerate.

Перепишем наш пример с использованием этой функции:

Смотрите, у функции enumerate первым параметром указывается перебираемая коллекция (любой итерируемый объект), а при переборе элементов она выдает кортеж из двух значений:

(индекс, значение элемента)

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

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

Вообще функция enumerate имеет следующий синтаксис:

Здесь sequence – это любой итерируемый объект; start – начальное значение индекса. Например, если вторым параметром указать 1, то индекс будет отсчитываться уже от 1:

И так далее. Давайте теперь разберемся, что возвращает функция enumerate? Возможно, вас сейчас удивила эта фраза: я же только что говорил, что на каждой итерации мы получаем кортеж из двух значений – индекса и самого элемента? Все так, но ключевым здесь является фраза «на каждой итерации». Сейчас я поясню, что имею в виду. Смотрите, если просто взять и вызвать эту функцию, а затем, результат вывести в консоль:

то увидим сообщение:

Никакого кортежа здесь нет, g – это итерируемый объект, то есть, объект-итератор, который можно перебирать с помощью функции next:

Именно это и делает цикл for. Он автоматически вызывает эту функцию, и уже на ее выходе формируется кортеж, который мы и видим на каждой итерации. Именно так следует воспринимать функцию enumerate, как объект-итератор. Фактически, ее (в упрощенном виде), можно записать вот так:

То есть, это просто дополнительная обертка над итерируемым объектом sequence. Вот что из себя представляет функция enumerate.

В заключении отмечу, как эта функция применяется к разным типам объектов:

Источник

Python функция enumerate()

Функция enumerate Python очень полезна и трудно описать в одном предложении её нужность и востребованность.

И все же, это супер полезная функция, которую многие новички и даже опытные питонщики не знают. Если сказать кратко, enumerate() позволяет перебирать коллекцию элементов, отслеживая индекс текущего элемента.

Этот код вернёт результат:

Производится итерация по списку names и генерация индекса для каждого элемента, увеличивая переменную счётчика, начиная с нуля.

Сделайте свои циклы более питоническими с enumerate()

Некоторые начинающие разработчики Python, пришедшие из C или Java, иногда используют range(len (. )) антипаттерн, чтобы поддерживать индекс во время итерации по списку с помощью цикла for:

С помощью функции enumerate() можно сделать эту циклическую конструкцию гораздо более «питонической» и идиоматической.

Обычно нет необходимости создавать индексы элементов вручную в Python – достаточно просто поручить эту работу функции enumerate(). И в результате код будет легче читаем и менее уязвим для опечаток.

Изменение стартового индекса

Еще одна полезная функция – возможность выбора начального индекса для перечисления. Функция enumerate() принимает необязательный аргумент, который позволяет установить начальное значение для внутренней переменной счетчика:

В приведенном выше примере вызов функции заменён на enumerate(names, 1), а дополнительный аргумент теперь начинает индексирование с единицы вместо нуля:

Как enumerate() работает за кулисами

Рассмотрим более подробно, как функция enumerate() работает за кулисами. Часть её магии заключается в том, что enumerate() реализована как итератор Python. Это означает, что индексы элементов генерируются лениво, сохраняя низкое потребление памяти и ускоряя выполнение программы.

В приведенном выше фрагменте кода выполняется то же перечисление, которое было приведёно в предыдущих примерах. Но вместо того, чтобы сразу перебирать результат вызова enumerate(), просто распечатывается возвращаемый объект в консоль Python.

Как вы можете видеть – это «enumerate object». Фактическии – это итератор. И, как уже было сказано, он генерирует свои выходные элементы лениво и один за другим, только когда их запрашивают.

Чтобы получить элементы «по требованию» достаточно вызвать встроенную функцию list() на итераторе:

Для каждого элемента во входном list (names) итератор, возвращаемый enumerate(), создает кортеж формы (индекс, элемент).

Источник

🐍 Python enumerate: упрощаем циклы с помощью счетчиков

Enumerate python что это. Смотреть фото Enumerate python что это. Смотреть картинку Enumerate python что это. Картинка про Enumerate python что это. Фото Enumerate python что это

Итерация с помощью циклов for

Цикл for в Python использует итерацию на основе коллекции. Это означает, что Python на каждой итерации назначает следующий элемент из iterable переменной цикла, как в этом примере:

Здесь значения состоят из трех строк: a, b и c. В Python списки – один из типов итерационных объектов iterable. В цикле for переменная имеет значение value. На каждой итерации ее значение устанавливается равным следующему элементу из values.

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

В этом примере index – целое число, отслеживающее, как глубоко вы находитесь в списке. На каждой итерации на экран выводится index и value. Последним шагом в цикле является обновление числа, хранящегося в index. Здесь может всплыть ошибка, если забыть обновить index:

В примере на каждой итерации index остается равным 0, т. к. нет кода для его обновления. Этот вид ошибки трудно отследить, особенно в длинных и сложных циклах.

Другой распространенный способ решения этой проблемы – использовать range() в сочетании с len() для автоматического создания index, и вам не придется помнить о его обновлении:

Одной из ошибок может быть отсутствие обновления value в начале каждой итерации.

Пример несколько ограничен, поскольку values должны разрешать доступ к своим элементам с помощью целочисленных индексов. Итерируемые объекты, разрешающие этот вид доступа, называют последовательностями.

В цикле for можно использовать любую итерацию, но только последовательности доступны по целочисленным индексам. Попытка получить доступ к элементам по индексу из генератора или итератора вызовет ошибку TypeError:

К счастью, функция enumerate() позволяет избежать все эти проблемы. Она доступна в Python с версии 2.3.

Использование enumerate()

Вы можете использовать enumerate() в цикле почти так же, как объект iterable. Вместо того чтобы помещать итерацию непосредственно после in в цикл for, вы помещаете ее в круглые скобки enumerate(). Придется немного изменить переменную цикла, как показано в примере:

Когда вы используете enumerate(), функция возвращает две переменные цикла: количество текущих итераций и значение элемента на текущей итерации.

Как и в обычном цикле for, переменные цикла могут быть названы как угодно (например, как count и value в примере выше). Вам не нужно помнить, что следует из итератора получить доступ к элементу и подвинуть индекс в конец цикла – все делается автоматически.

Функция enumerate() имеет дополнительный аргумент, который можно использовать для управления начальным значением счетчика. По умолчанию оно равно 0, и если вы хотите получить первый элемент списка, используйте индекс 0:

Здесь можно увидеть, что доступ к значениям с индексом 0 дает первый элемент a. Бывает так, что необходимо запустить счетчик не с 0. В этом случае используйте аргумент start для enumerate(), чтобы изменить начальный счетчик:

Практика с enumerate()

Допустимо применять enumerate () в любой ситуации, например, когда нужно использовать count и элемент в цикле. Имейте в виду, что функция enumerate () увеличивает количество на единицу на каждой итерации. Далее рассмотрим некоторые варианты использования enumerate ().

Количество итеративных элементов

В предыдущем разделе вы видели, как использовать enumerate() для печати. Разберем скрипт, читающий файлы reST и сообщающий пользователю о проблемах с форматированием.

Не беспокойтесь, если что-то не понятно, т. к. цель – показать реальное использование enumerate():

check_whitespace() принимает один аргумент, lines, который является строками обрабатываемого файла. Сценарий возвращает номер строки, сокращенный как lno и line, а далее идет проверка на нежелательные символы: \r, \t, табуляции и пробелы.

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

Условные операторы для пропуска элементов

Иногда есть необходимость выполнить действие на первой итерации цикла:

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

Можно комбинировать математические операции с условиями. Например, если вам понадобится возвращать элементы из итерационной модели, имеющие четный индекс. Это делается следующим образом:

В цикле for проверяется, равен ли остаток от деления index на 2 нулю и если так, то элемент добавляется к значениям.

Вы можете сделать код более понятным, используя list comprehension без инициализации пустого списка:

В этом примере even_items() использует list comprehension, а не цикл for для извлечения каждого элемента из списка, индекс которого является четным числом.

Вы можете проверить, что even_items() работает как ожидалось, получив четные элементы из диапазона целых чисел от 1 до 10. Результатом будет [2, 4, 6, 8, 10]:

even_items() возвращает четные элементы из seq. Теперь можно проверить, как эта штука будет работать с буквами алфавита ASCII:

Строка alphabet содержит двадцать шесть строчных букв ASCII-алфавита. Вызов even_items() и передача alphabet возвращает список чередующихся букв.

Строки в Python – это последовательности, которые можно использовать как в циклах, так и в целочисленном индексировании. В случае со строками нужны квадратные скобки для реализации той же функциональности, что и в even_items():

Понимание enumerate()

До этого мы рассматривали примеры использования enumerate(). Теперь стоит глубже изучить, как эта функция работает.

Чтобы лучше понять, как работает enumerate(), реализуйте собственную версию с помощью Python. Она должна следовать двум требованиям:

Один из способов написания функции по данным спецификациям приведен в документации Python:

Вы создаете список четырех сезонов для работы. Далее показываете, что вызов my_enumerate() с ними в качестве последовательности создаст объект генератора. Это происходит, поскольку ключевое слово yield отправляет значения обратно вызывающему объекту.

Наконец создается два списка из my_enumerate(): в одном начальное значение остается по умолчанию 0, а в другом start изменяется на 1. В обоих случаях вы получаете список кортежей, в которых первым элементом является счетчик, а вторым – значение из seasons.

Мы реализовали эквивалент enumerate() всего из нескольких строк кода, хотя оригинальный код на C для enumerate() несколько больше. Это означает, что Python очень быстрый и эффективный.

Распаковка аргументов с помощью enumerate()

Когда вы используете enumerate() в цикле for, вы говорите Python работать с двумя переменными: одной для подсчета и одной для значения. Все это можно сделать, используя распаковку аргументов.

Идея в том, что кортеж может быть разбит на несколько переменных в зависимости от длины последовательности. Например, если распаковать кортеж из двух элементов в две переменные:

Сначала создается кортеж с элементами 10 и «а». Затем вы распаковываете его в first_elem и second_elem, присваивая по одному из значений кортежа.

Когда вызывается enumerate() и передается последовательность значений, Python возвращает итератор, а когда вы запрашиваете у итератора следующее значение, он отдает кортеж с двумя элементами: элемент кортежа (счетчик) и значение из переданной последовательности.

В этом примере создается список значений с двумя элементами «a» и «b». Затем значения передаются в enumerate() и присваивается возвращаемое значение enum_instance. Когда выводится enum_instance, можно видеть, что это экземпляр enumerate() с определенным адресом памяти.

Повторный вызов next() дает еще один кортеж, на этот раз с числом 1 и вторым элементом из значений «b». Наконец, вызов next() еще раз вызывает StopIteration, так как больше нет возвращаемых значений. Когда метод используется в цикле for, Python автоматически вызывает next() перед началом каждой итерации, пока StopIteration растет.

Если функция возвращает кортеж, можно использовать распаковку аргументов для назначения элементов кортежа нескольким переменным. Это мы делали выше, используя две переменные цикла.

Еще один способ увидеть распаковку аргументов – использовать цикл for со встроенным zip(), позволяющим перебирать две или более последовательности одновременно. На каждой итерации zip() возвращает кортеж, который собирает элементы из всех переданных последовательностей:

В цикле элементы сопоставляются, а затем выводятся. Вы можете объединить zip() и enumerate(), используя вложенную распаковку аргументов:

В цикле for используется вложенный zip() в enumerate(), т. е. каждый раз, когда цикл повторяется, enumerate() выдает кортеж с первым значением в качестве count и вторым в качестве другого кортежа с элементами из аргументов zip().

Заключение

В этой статье мы изучили:

Вы узнали много нового и теперь способны упростить ваши циклы, чтобы сделать код на Python более профессиональным.

Источник

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

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

Enumerate python что это. Смотреть фото Enumerate python что это. Смотреть картинку Enumerate python что это. Картинка про Enumerate python что это. Фото Enumerate python что это

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

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

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

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

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

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

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

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

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

Итоги

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

Источник

Python Tips, Tricks, and Hacks (часть 2)

Содержание

2 Списки

2.2 Свёртка списка

К сожалению, нельзя написать программу только с помощью генераторов списков. (Я шучу… конечно, можно.) Они могут отображать и фильтровать, но нет простого способа для свертки списка. Под этим понятием я подразумеваю применение функции к первым двум элементам списка, а затем к получившемуся результату и следующему элементу, и так до конца списка. Можно реализовать это через цикл for:

А можно воспользоваться встроенной функцией reduce, принимающей в качестве аргументов функцию от двух параметров и список:

Не так красиво, как генераторы списков, но короче обычного цикла. Стоит запомнить этот способ.

2.3 Прохождение по списку: range, xrange и enumerate

Помните, как в языке C для цикла for вы использовали переменную-счетчик вместо элементов списка? Возможно, вы уже знаете, как имитировать это поведение в Python с помощью range и xrange. Передавая число value функции range, мы получим список, содержащий элементы от 0 до value-1 включительно. Другими словами, range возвращает индексы списка указанной длины. xrange действует похоже, но более эффективно, не загружая весь список в память целиком.

Проблема в том, что обычно вам всё равно нужны элементы списка. Что толку от индексов без них? В Python есть потрясающая встроенная функция enumerate, которая воозвращает итератор для пар индекс → значение:

Еще один плюс состоит в том, что enumerate выглядит более читаемо, чем xrange(len()). Поэтому range и xrange полезны, наверно, только для создания списка с нуля, а не на основе других данных.

2.4 Проверка всех элементов списка на выполнение условия

Допустим, нам надо проверить, выполняется ли условие хотя бы для одного элемента. До Python 2.5 можно было писать так:

Аналогично, может возникнуть задача проверки, что все элементы удовлетворяют условию. Без Python 2.5 придется писать так:

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

В Python 2.5 есть более простой путь — встроенная функция all. Легко догадаться, что она прекращает проверку после первого элемента, не удовлетворяющего условию. Эта функция работает абсолютно аналогично предыдущей.

2.5 Группировка элементов нескольких списков

Встроенная функция zip используется для сжимания нескольких списков в один. Она возвращает массив кортежей, причем n-й кортеж содержит n-е элементы всех массивов, переданных в качестве аргументов. Это тот случай, когда пример — лучшее объяснение:

Эта вещь часто используется как итератор для цикла for, извлекающая три значения за одну итерацию («for letter, number, squares in zipped_list»).

2.6 Еще несколько операторов для работы со списками

Ниже перечислены встроенные функции, в качестве аргумента принимающие любой итерируемый объект.
max и min возвращают наибольший и наименьший элемент соответственно.
sum возвращает сумму всех элементов списка. Опциональный второй параметр задает начальную сумму (по умолчанию 0).

2.7 Продвинутые логические операции с типом set.

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

Довольно распространенная задача — убедиться, что элементы списка уникальны. Это просто, достаточно преобразовать его в сет и проверить, изменилась ли длина:

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

3 Словари

3.1 Создание словаря с помощью именованных аргументов

Когда я начал изучать Python, я полностью пропустил альтернативный способ создания словаря. Если передать конструктору dict именованные аргументы, они будут добавлены в возращаемый словарь. Конечно, на его ключи накладываются те же ограничения, что и на имена переменных. Вот пример:

Этот способ немного очищает код, избавляя вас от летающих вокруг кавычек. Я часто использую его.

3.2 Преобразование словаря в список
3.3 Преобразование списка в словарь

Обратная операция — превращение списка, содержащего пары ключ-значение, в словарь — делается так же просто:

Вы можете комбинировать методы, добавив именованные аргументы:

Превращать списка и словари друг в друга довольно удобно. Но следующий совет просто потрясающий.

3.3 «Dictionary Comprehensions»

Конечно, необязательно начинать и заканчивать словарем, можно в некоторых местах использовать и списки.

Это чуть менее читабельно, чем строгие генераторы списков, но я считаю, что это лучше, чем большой цикл for.

Источник

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

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