Python dict for items

4 способа перебора словаря в Python

Словари Python сопоставляют ключи со значениями и сохраняют их в коллекции или массиве. Словарь — это ассоциативный массив, в котором произвольные ключи сопоставляются со значениями. Словари — это итерации, которые поддерживают доступ к элементам с использованием целочисленных индексов, словарей индексов ключей. Ключами словаря может быть любой объект с функциями __hash__() и __eq__().

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

Различные способы перебора словаря

В основном существует четыре способа перебора словаря в Python:

  1. Итерация через .items()
  2. Перебор .keys()
  3. Перебор .values()
  4. Итерация по ключам напрямую.

Давайте обсудим все подходы один за другим.

Итерация словаря через .items()

Метод items() возвращает объект представления, который отображает список пар словаря (ключ, значение).

Синтаксис

Представления можно обходить, чтобы получить соответствующие данные, поэтому вы можете перебирать словарь в Python, используя объект представления, возвращаемый функцией .items().

Давайте повторим объект dict_items() с помощью цикла for.

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

Если вы посмотрите на отдельные элементы, выдаваемые методом .items(), вы заметите, что они являются объектами-кортежами. Теперь вы можете распаковать кортеж, чтобы просмотреть ключи и значения словаря.

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

Давайте перейдем ко второму способу перебора словаря Python.

Итерация по .keys()

Метод keys() возвращает объект представления, который отображает список всех ключей словаря. Если вам просто нужно работать с ключами словаря, вы можете использовать метод dict.keys(), который возвращает новый объект представления, содержащий ключи.

Синтаксис

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

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

Теперь, что насчет значений, как мы можем получить значения словаря? Ответ на этот вопрос: оператор индексации( [ ] ). Вы можете получить доступ к значениям словаря с помощью оператора индексации.

Читайте также:  Css максимальное число строк

Таким образом, вы одновременно получаете доступ к ключам (key) и значениям (dataPython dict for items) словаря данных и можете выполнять над ними любые операции.

Перебор по .values() в словаре Python

Метод values() возвращает объект представления, который отображает список всех значений в словаре. До сих пор мы видели методы dict.items() и dict.keys() для итерации словаря. Следующий метод предназначен для повторения values () словаря.

Синтаксис

Здесь объект data_values, возвращаемый функцией .values(), обеспечивает динамическое представление ключей словаря данных. Представление data_values можно использовать для перебора значений данных. Чтобы перебрать словарь в Python с помощью .keys(), вам просто нужно вызвать .values() в заголовке цикла for.

Используя метод .values(), вы получите доступ только к значениям данных, не имея дело с ключами.

Обход через direct клавиши и []

Если вы не хотите использовать методы dict.keys() и dict.values() и по-прежнему хотите напрямую перебирать ключи и значения в Python, мы все равно можем это сделать.

Словари Python являются объектами сопоставления. Это означает, что они наследуют некоторые специальные методы, которые Python использует внутри для вычисления некоторых операций. Эти методы названы с использованием соглашения об именах с добавлением двойного подчеркивания в начале и в конце имени функции.

Для сопоставлений (например, словарей) __iter__() должен перебирать ключи. Это означает, что если вы поместите словарь непосредственно в цикл for, Python автоматически вызовет .__iter__() для этого словаря, и вы получите итератор по его ключам. Затем мы использовали обычные способы получения значения словаря с помощью оператора индексации.

Источник

Эффективный обход словарей в цикле в Python

Словарь (dictionary, dict) — это ассоциативный массив, который позволяет сохранять значения по ключам.

Это очень важная, даже можно сказать основополагающая структура данных, которая используется в Python под капотом буквально повсюду: модули, классы, объекты, locals() , globals() — все это так или иначе работает лишь благодаря словарям.

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

В Python большое внимание уделяется циклам. Правильно написанный заголовок цикла содержит много ценной информации: по чему итерируемся и какие данные будут использоваться в теле цикла. Это помогает читателю понять (или хотя бы предположить), что именно будет производиться в теле цикла, даже не смотря в него. Неправильно написанный цикл, который не выражает напрямую задумку автора, наоборот, сбивает читателя с толку и заставляет читать код целиком, возможно, даже не один раз.

Есть несколько способов обойти словарь в цикле. Очень важно научиться выбирать наиболее подходящий.

Что будет если просто попытаться обойти словарь в цикле?

Объявим словарь с отношением различных валют к российскому рублю, который нам по какой-то причине нужно обойти:

currencies = "rub": 1, "usd": 69.78, "eur": 78.28> 

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

for something in currencies: print(something) 

Словарь и правда поддерживает протокол итераций, но словарь не так прост, как другие объекты, которые мы упомянули выше. Словарь состоит из нескольких частей, ведь словарь — это отношение между ключами и значениями. Получается, что теоретически цикл по словарю может получать либо ключи, либо значения, либо пары (ключ, значение). Попробуете угадать, что же именно выведет код выше?

То есть обход словаря в цикле будет возвращать только ключи этого словаря.

Пожалуй, задать такое поведение по умолчанию — это очень логичное решение со стороны разработчиков Python. Было бы намного внезапнее, если бы цикл по словарю получал значения. Вариант с кортежами (ключ, значение) в качестве поведения по умолчанию мне кажется не таким уж плохим, но имеем то, что имеем.

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

Как обойти в цикле ключи словаря?

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

У словаря есть метод .keys() , который возвращает представление словаря (dict view), возвращающее ключи.

Что такое представление словаря? Это некий объект, который предоставляет доступ к данным в словаре, либо к части этих данных, и работает по следующим принципам:

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

Создадим такое представление словаря по ключам:

dict_keys = currencies.keys() print(dict_keys) # dict_keys(['rub', 'usd', 'eur']) 

Давайте добавим новый ключ в словарь:

currencies["jpy"] = 0.65 print(dict_keys) # dict_keys(['rub', 'usd', 'eur', 'jpy']) 

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

Обратите внимание, что представление словаря — это не список, а совершенно другой объект. Представление словаря не поддерживает извлечение значений по индексам:

dict_keys[0] # Traceback (most recent call last): # File "", line 1, in # TypeError: 'dict_keys' object is not subscriptable 

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

for key in currencies.keys(): print(key) # rub # usd # eur # jpy 

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

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

Как обойти в цикле значения словаря?

По аналогии с ключами, из словаря можно извлечь только значения, без ключей. Это делается через метод словарей .values() , который возвращает представление словаря, содержащее только значения.

Это представление работает по тем же правилам, что и возвращаемое методом .keys() .

Вот как можно обойти в цикле только значения словаря, без ключей:

for value in currencies.values(): print(value) # 1 # 69.78 # 78.28 # 0.65 

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

Как обойти в цикле и ключи, и значения словаря?

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

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

Это представление работает по точно таким же правилам, как .keys() и .values() . Единственное отличие этого представления от предыдущих состоит в том, что оно возвращает не единичные значения, а кортежи из двух значений.

for item in currencies.items(): # item — это кортеж (ключ, значение) print(item[0], item[1]) # rub 1 # usd 69.78 # eur 78.28 # jpy 0.65 

В Python есть возможность распаковывать итерируемые объекты, такие как кортежи, в различные переменные. Давайте на примере посмотрим как это работает:

point = (1, 2, 3) x, y, z = point print(x) # 1 print(y) # 2 print(z) # 3 

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

Вот так можно обойти ключи и значения словаря, сохраняя ключ и значение в разные переменные прямо в заголовке цикла при помощи распаковки кортежа:

for key, value in currencies.items(): print(key, value) # rub 1 # usd 69.78 # eur 78.28 # jpy 0.65 

Заключение

При обходе словаря стоит руководствоваться следующей логикой:

  • если в цикле используются и ключи, и значения словаря, то нужно использовать метод .items() ;
  • если в цикле используются только значения словаря, а ключи не важны, то нужно использовать метод .values() ;
  • если в цикле нужны ключи словаря и ничего больше, то нужно использовать метод .keys() .

Идеоматичный код проще читается и, как правило, работает быстрее.

Посмотрите запись классического выступления Реймонда Хеттингера, где он рассказывает про написание идеоматичного код. Много внимания уделяется циклам и словарям.

Обратите внимание, что это запись выступления от 2013 года, когда ещё вовсю был в ходу Python 2. В выступлении часто сравнивается Python 2 и Python 3. Не запутайтесь.

Если понравилась статья, то подпишитесь на уведомления о новых постах в блоге, чтобы ничего не пропустить!

Ссылки

  • очень подробный разбор по обходу словарей на RealPython;
  • документация про представления словарей;
  • и, конечно же, посмотрите выступление Реймонда Хеттингера, обожаю этого чувака.

Источник

Оцените статью