For each python key

Iterate dictionary (key and value) with for loop in Python

In Python, to iterate through a dictionary ( dict ) with a for loop, use the keys() , values() , and items() methods. You can also get a list of all keys and values in the dictionary with those methods and list() .

Consider the following dictionary as an example:

You can iterate keys by directly using the dictionary object in a for loop.

for k in d: print(k) # key1 # key2 # key3 

See the following article for the basics of for loops in Python.

Iterate dictionary keys: keys()

As mentioned above, you can iterate dictionary keys by directly using the dictionary object, but you can also use keys() . The result is the same, but keys() may clarify the intent to the reader of the code.

for k in d.keys(): print(k) # key1 # key2 # key3 

The keys() method returns dict_keys , which can be converted to a list with list() .

keys = d.keys() print(keys) print(type(keys)) # dict_keys(['key1', 'key2', 'key3']) # k_list = list(d.keys()) print(k_list) print(type(k_list)) # ['key1', 'key2', 'key3'] # 

You can use dict_keys to perform set operations. See the following article for details.

Iterate dictionary values: values()

To iterate dictionary values, use the values() method.

for v in d.values(): print(v) # 1 # 2 # 3 

The values() method returns dict_values , which can be converted to a list with list() .

values = d.values() print(values) print(type(values)) # dict_values([1, 2, 3]) # v_list = list(d.values()) print(v_list) print(type(v_list)) # [1, 2, 3] # 

Iterate dictionary key-value pairs: items()

To iterate dictionary key-value pairs, use the items() method.

for k, v in d.items(): print(k, v) # key1 1 # key2 2 # key3 3 

You can also receive the key-value pairs as a tuple of (key, value) :

for t in d.items(): print(t) print(type(t)) print(t[0]) print(t[1]) print('---') # ('key1', 1) # # key1 # 1 # --- # ('key2', 2) # # key2 # 2 # --- # ('key3', 3) # # key3 # 3 # --- 

The items() method returns dict_items , which can be converted to a list with list() .

items = d.items() print(items) print(type(items)) # dict_items([('key1', 1), ('key2', 2), ('key3', 3)]) # i_list = list(d.items()) print(i_list) print(type(i_list)) # [('key1', 1), ('key2', 2), ('key3', 3)] # print(i_list[0]) print(type(i_list[0])) # ('key1', 1) # 

You can also use dict_items to perform set operations. See the following article for details.

  • Unpack and pass list, tuple, dict to function arguments in Python
  • Merge multiple dictionaries and add items to a dictionary in Python
  • Swap dictionary keys and values in Python
  • Get value from dictionary by key with get() in Python
  • Get maximum/minimum values and keys in Python dictionaries
  • Add an item if the key does not exist in dict with setdefault in Python
  • Create a dictionary in Python (<>, dict(), dict comprehensions)
  • Sort a list of dictionaries by the value of the specific key in Python
  • Change dictionary key in Python
  • Get key from value in dictionary in Python
  • Remove an item from a dictionary in Python (clear, pop, popitem, del)
  • Pretty-print with pprint in Python
  • Check if key/value exists in dictionary in Python
  • Set operations on multiple dictionary keys in Python
  • Extract specific key values from a list of dictionaries in Python

Источник

Эффективный обход словарей в цикле в 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;
  • документация про представления словарей;
  • и, конечно же, посмотрите выступление Реймонда Хеттингера, обожаю этого чувака.

Источник

Читайте также:  Операторы языка python вывод данных
Оцените статью