Словари (dict) и работа с ними. Методы словарей
Сегодня я расскажу о таком типе данных, как словари, о работе со словарями, операциях над ними, методах, о генераторах словарей.
Словари в Python — неупорядоченные коллекции произвольных объектов с доступом по ключу. Их иногда ещё называют ассоциативными массивами или хеш-таблицами.
Чтобы работать со словарём, его нужно создать. Сделать это можно несколькими способами. Во-первых, с помощью литерала:
Во-вторых, с помощью функции dict:
В-третьих, с помощью метода fromkeys:
В-четвертых, с помощью генераторов словарей, которые очень похожи на генераторы списков.
Теперь попробуем добавить записей в словарь и извлечь значения ключей:
: Как видно из примера, присвоение по новому ключу расширяет словарь, присвоение по существующему ключу перезаписывает его, а попытка извлечения несуществующего ключа порождает исключение. Для избежания исключения есть специальный метод (см. ниже), или можно перехватывать исключение.
Что же можно еще делать со словарями? Да то же самое, что и с другими объектами: встроенные функции, ключевые слова (например, циклы for и while), а также специальные методы словарей.
Методы словарей
dict.clear() — очищает словарь.
dict.copy() — возвращает копию словаря.
classmethod dict.fromkeys(seq[, value]) — создает словарь с ключами из seq и значением value (по умолчанию None).
dict.get(key[, default]) — возвращает значение ключа, но если его нет, не бросает исключение, а возвращает default (по умолчанию None).
dict.items() — возвращает пары (ключ, значение).
dict.keys() — возвращает ключи в словаре.
dict.pop(key[, default]) — удаляет ключ и возвращает значение. Если ключа нет, возвращает default (по умолчанию бросает исключение).
dict.popitem() — удаляет и возвращает пару (ключ, значение). Если словарь пуст, бросает исключение KeyError. Помните, что словари неупорядочены.
dict.setdefault(key[, default]) — возвращает значение ключа, но если его нет, не бросает исключение, а создает ключ со значением default (по умолчанию None).
dict.update([other]) — обновляет словарь, добавляя пары (ключ, значение) из other. Существующие ключи перезаписываются. Возвращает None (не новый словарь!).
dict.values() — возвращает значения в словаре.
Для вставки кода на Python в комментарий заключайте его в теги
Как записать словарь в файл?
Или как json, но там, конечно, меньшее разнообразие типов, да и объекты классов просто так не запихнешь без предварительной сериализации.
14 июн 2019 в 14:03
@gil9red я думал добавить сохранение словаря в Json. Но не смотря на внешнее сходство, словарь и json объект ни одно и тоже, что только добавит путаницы в голову ТС.
14 июн 2019 в 14:20
- python
- python-3.x
- python-3.7
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.21.1314
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Использование словарей в Python на практике
Сегодня мы поговорим про использование словарей в Python на практике. Вы узнаете, как создать словарь, загрузить в него данные, отфильтровать их, получать и сортировать значения, а также выполнять другие операции со словарем.
Словари Python и набор инструментов Data Science
Для работы с данными в Python их нужно хранить в соответствующей структуре данных. Словарь — одна из специальных встроенных структур данных Python. Название говорит само за себя: данные хранятся в виде значений, к которым можно получить доступ с помощью ключа.
Если вы ищете слово «python» в обычном толковом словаре, вы обычно начинаете с поиска той части книги, где слова начинаются с «р». Затем среди них выбираете ту часть, где вторая буква — «у». Потом ищете «t» и так далее, пока не найдете полное слово. Словарная статья сообщит вам, что «python» — это большая неядовитая змея, сжимающая свою добычу, или язык программирования высокого уровня.
Бумажный словарь является хорошим помощником потому, что слова в нем упорядочены в алфавитном порядке. И, немного потренировавшись, вы сможете находить нужные слова очень быстро.
Словарь в Python работает аналогичным образом. Сохраненные элементы словаря могут быть извлечены очень быстро по их ключу. То есть в словарях, в отличие от списков, Python отслеживает, где найти определенную информацию.
Как создать словарь Python
Предположим, вы проводите инвентаризацию фруктов в корзине. Вы сохраняете количество каждого типа фруктов в словаре. Существует несколько способов создания словаря, но в этом уроке мы не будем усложнять. Полный обзор можно найти в документации Python по словарям.
Наиболее важный отличительный признак словаря — фигурные скобки <> . Кроме того, для каждого элемента словаря нужно разделение ключа и значения двоеточием : .
Приведенная ниже переменная fruit — словарь. Вы можете получить доступ к любому элементу из этого словаря, поместив ключ в квадратные скобки [] . То же самое можно сделать еще и с помощью метода .get() .
>>> fruit = # Обращаемся к словарю fruit напрямую (без метода get) и выводим значение ключа "banana" >>> fruit["banana"] # 4 # Выводим значение ключа "banana" при помощи метода get >>> fruit.get("banana") # 4
Загрузка данных в словарь в Python
Теперь давайте поместим в словарь какие-нибудь настоящие данные, а точнее — вложенный словарь. То есть в словаре в качестве значения будет не цифра или строка, а другой словарь.
Вложенность позволяет легко хранить в словаре таблицы или матрицы.
Данные, которые мы будем использовать, это обзоры книги Donna Tartt «The Goldfinch». Они взяты из набора обзоров книг Amazon из репозитория twielfaert. Эти обзоры были сохранены в простом файле csv, со значениями, разделенными табуляцией. То есть это обычный текстовый файл со столбцами.
Таблица содержит четыре столбца: оценка обзора, URL-адрес, заголовок обзора и текст обзора ( review score , url , review title и review text ).
Есть несколько способов представить это в виде словаря. К примеру, можно взять URL-адреса в качестве ключей словаря и поместить другие столбцы во вложенный словарь.
import urllib.request import random # Загружаем данные из удаленного источника (URL) file = urllib.request.urlopen("https://gist.githubusercontent.com/twielfaert/a0972bf366d9aaf6cb1206c16bf93731/raw/dde46ad1fa41f442971726f34ad03aaac85f5414/Donna-Tartt-The-Goldfinch.csv") f = file.read() # Преобразовываем поток битов в строки text = f.decode(encoding='utf-8',errors='ignore') # Делим единую строку на отдельные строки lines = text.split("\n") # Инициализируем словарь reviews = <> # Заполняем словарь for line in lines: l = line.strip().split("\t") # Это лишь тренировка, позволяющая увидеть, что поступает в словарь score = l[0] title = l[2] review = l[3] reviews[id] = # Берем рандомный ключ словаря и выводим его значение print(reviews[random.choice(list(reviews.keys()))])
В этом случае нам посчастливилось получить набор данных, в котором нет пропущенных значений. Но не всегда так везет. Реальные наборы данных «из дикой природы» часто беспорядочны (неправильное форматирование, ошибки кодирования, отсутствующие данные и т.д.).
Однако вы можете легко проверить, все ли ключи на месте, сравнив количество строк в файле с количеством ключей в словаре.
# Считаем количество строк в файле print("Number of lines: " + str(len(lines))) # Считаем ключи словаря, их должно быть столько же, сколько строк в файле print("Number of dictionary keys: " + str(len(reviews.keys())))
Как отфильтровать словарь в Python
Теперь, когда обзоры Amazon сохранены в словаре, пришло время попробовать поработать с ними. Допустим, вас интересуют плохие отзывы. Вы хотите посмотреть, что написали люди в отзывах с оценками в 1,0 балл.
Оценки обзора хранятся в значениях словаря, что означает, что нам придется перебирать словарь в цикле. К сожалению, мы не можем просто использовать цикл for для просмотра словаря.
Элементы словаря в Python имеют не только ключ и значение, но и специальный итератор для циклического перебора. Вместо for item in dictionary нам нужно использовать for key, value in dictionary.items() . То есть нужно использовать этот конкретный итератор и две переменные (ключ и значение) вместо одной. Также есть отдельные итераторы для ключей ( .keys() ) и значений ( .values() ).
Мы сохраним ключи обзоров с низкой оценкой в списке с именем lowscores , чтобы позже иметь возможность использовать этот список повторно.
# Сохраняем ключи обзоров с низкой оценкой (1.0) в список lowscores = [] for key, value in reviews.items(): if float(value["score"]) == 1.0: # Приводим оценку к float lowscores.append(key) # Выводим все отзывы с низкой оценкой for item in lowscores: print(reviews[item])
Операции со словарем в Python
Если словарь, содержащий полный набор данных, большой, разумнее использовать только что полученный список lowscores для создания совершенно нового словаря. Таким образом вам не придется удерживать в памяти весь большой словарь для дальнейшей работы с отзывами с низкими оценками. Вы сможете просто работать с соответствующим подмножеством исходных данных.
Для создания нового словаря мы используем ключи, хранящиеся в lowscores . Для этого есть два варианта: просто извлечь соответствующие элементы из исходного словаря с помощью метода .get() , оставляя оригинал нетронутым, или использовать .pop() , который навсегда удаляет ненужные элементы из исходного словаря.
Код может выглядеть следующим образом:
subset = dict([(k, reviews.get(k)) for k in lowscores])
Возможно, код, записанный в одну строку, выглядит непривычно для вас. Этот стиль называется генератором словарей. На самом деле это замаскированный цикл for , перебирающий элементы из lowscores , извлекающий значения из обзоров и использующий их для заполнения нового словаря. Это очень похоже на генератор списка, только вместо списка выводит словарь.
Однако не рекомендуется использовать генераторы, если вы еще не знакомы с ними. Цикл for легче читать и понимать.
Вы можете сравнить традиционный стиль цикла for с генератором словаря и убедиться, что они действительно дают одинаковый результат:
# Использование цикла for forloop = <> for k in lowscores: forloop[k] = reviews[k] # Добавляем подходящий метод для получения соответствующих элементов из словаря `reviews` dictcomp = # Проверяем, равны ли полученные объекты print(forloop == dictcomp)
Предположим, теперь вы хотите переупорядочить словарь, чтобы в качестве ключей использовались оценки обзоров, а не идентификаторы. Для этого вы можете использовать цикл for , указав ключи и значения и создав новый словарь. Вам нужно будет получить score из первоначально словаря, чтобы использовать его в качестве нового ключа.
Чтобы немного упростить код, создадим новый словарь как объект newvalues в отдельной строке перед заполнением scoredict ключами-идентификаторами и словарем newvalues в качестве значений:
from collections import defaultdict scoredict = defaultdict(list) for key, value in reviews.items(): newvalues = # Используем 'score' из значений (!) исходного словаря как ключ для нового scoredict[value['score']].append(newvalues) # Выводим ключи словаря, чтобы удостовериться, что это оценки обзоров print(scoredict.keys())
Как сортировать словари в Python
Поскольку мы загрузили в словарь реальный набор данных, мы можем выполнить его базовый анализ. Если нас интересуют слова, которые связаны с негативным отношением к роману, можно провести низкоуровневый анализ настроений. Для этого можно составить частотный список слов в негативных отзывах (оценка 1,0).
Нам нужно немного обработать текст отзыва, удалив HTML-теги и переведя слова в верхнем регистре в нижний.
Теги мы удалим при помощи регулярного выражения: re.sub("<.*?>", "") . Регулярные выражения — очень полезный инструмент при работе с текстовыми данными. Подробнее о них можно почитать в статье «Регулярные выражения в Python». В данном случае мы захватываем части строки, которые начинаются с символа .Части строки, соответствующие этому шаблону, удаляются путем замены «ничем» (пустые кавычки).
Также в Python есть встроенная функция для перевода букв в нижний регистр. К интересующей нас строке нужно просто добавить .lowercase() .
Затем мы создаем частотный словарь, используя defaultdict вместо обычного словаря. Это гарантирует, что каждый «ключ» будет инициализирован, и мы сможем просто увеличить частоту на 1.
Без defaultdict при попытке обратиться к несуществующему ключу (чтобы увеличить счетчик) Python выдал бы ошибку. Это можно обойти, сначала проверив, есть ли ключ в словаре. Однако это решение куда менее элегантно, чем использование defaultdict .
import re # Import defaultdict from collections import defaultdict freqdict = defaultdict(int) for item in lowscores: review = reviews[item]["review"] cleantext = re.sub(r'<.*?>', '', review).strip().split() # Удаляем HTML-теги и делим обзор на слова (разделенные пробелами) for word in cleantext: # Переводим все в нижний регистр word = word.lower() # Увеличиваем счетчик на единицу freqdict[word] += 1 print(freqdict)
После того, как частотный словарь готов, нам все еще нужно отсортировать ключи по значению в порядке убывания. Это нужно для того, чтобы быстро увидеть, какие слова являются наиболее частотными.
Поскольку обычные словари (в том числе defaultdict ) не могут быть упорядочены, нам нужен другой класс. Для этой цели отлично подойдет OrderedDict . Он хранит словарь в порядке добавления элементов. То есть нужно сперва отсортировать элементы, а затем сохранить их в новом OrderedDict .
Сортировка с помощью sorted()
Функция sorted() принимает 3 аргумента. Первый — это объект, который вы хотите отсортировать, т.е. наш частотный словарь. Помните, однако, что доступ к парам ключ-значение в словаре возможен только через функцию .items() . Если вы забудете об этом, Python вернет первый попавшийся ключ. Другими словами: если вы перебираете словарь и ваш код ведет себя странно, проверьте, добавили ли вы функцию .items() .
Второй аргумент указывает, какая часть первого аргумента должна использоваться для сортировки: key=lambda item: item[1] . Первая часть говорит сама за себя: вы хотите, чтобы ключи были отсортированы.
Лямбда-функция — это анонимная функция, которую нельзя вызывать извне. Это альтернативный способ перебрать весь диапазон объектов с помощью одной функции. В этом случае она просто использует значение словаря ( item[1] , при этом item[0] является ключом) в качестве аргумента для сортировки.
Последний аргумент, reverse , указывает, должна ли сортировка проходить по возрастанию или по убыванию. В этом случае мы хотим видеть наиболее часто встречающиеся слова вверху. Поэтому мы должны явно указать, что reverse=True .
Если бы вы сейчас посмотрели на верхнюю часть отсортированных элементов, вы были бы разочарованы словами, которые доминируют в этом частотном списке. Это были бы просто «служебные слова», такие как «the», «and», «a» и т.д. В английском (и, конечно, многих других языках) полно этих слов. Однако они в основном используются для связки слов и сами по себе совершенно бессмысленны.
В текстовой аналитике используются так называемые стоп-листы, чтобы исключить из анализа эти часто встречающиеся слова. Мы применим более простой подход, проигнорировав первые 10% слов и рассматривая только те слова, которые входят в 90% наиболее часто встречающихся.
Вы увидите, что в верхней части этого списка есть более интересные негативно окрашенные слова, такие как “uncomfortable” (неудобно) и “frustrating” (разочаровывает). Однако есть и позитивные слова, такие как “captivating” (захватывающий) и “wonderfully” (замечательно).
Вы можете сами поэкспериментировать с нарезкой, чтобы увидеть, в каких частях данных сможете найти интересные слова.
from collections import OrderedDict # Создаем упорядоченный словарь ordict = OrderedDict(sorted(freqdict.items(), key=lambda item: item[1], reverse=True)) # Игнорируем верхние 10% top10 = int(len(ordict.keys())/10) # Выводим первые 100 слов из оставшихся 90% print(list(ordict.items())[top10:top10+100])
Словарь vs. список Python, массив NumPy и Pandas DataFrame
Словари являются важной структурой данных, встроенной в Python. Они позволяют нам помещать данные в объекты Python для их дальнейшей обработки.
Словари, наряду со списками и кортежами, — одна из основных и наиболее мощных и гибких структур данных, которые может предложить Python. Однако в последнее время большая часть функциональности словаря может быть заменена Pandas. Это библиотека Python, которая позволяет выполнять большую часть обработки и анализа данных.
Если есть готовые библиотеки, зачем утруждать себя пониманием того, на что способны словари?
Что ж, всегда полезно научиться ходить, прежде чем пытаться бегать.
Такие библиотеки, как Pandas, позволяют работать с данными быстрее и эффективнее. С ними не приходится беспокоиться о том, как хранятся данные. Однако Pandas также использует словари (наряду с другими расширенными структурами данных, такими как массив NumPy) для хранения своих данных. Поэтому, прежде чем начинать работать с Pandas, все же полезно узнать, как работает словарь.
Даже при использовании Pandas иногда рекомендуется использовать словари. Например, когда значения необходимо просто сопоставить, использование объекта Pandas будет неэффективным и излишним.
Наконец, Pandas содержит функции для преобразования словаря в Pandas DataFrame и наоборот. Кроме того, датафреймы могут содержать словари. И то, и другое — очень полезные инструменты для работы с данными.
Заключение
Поздравляем! Вы одолели эту длинную и познавательную статью-руководство по использованию словарей Python на практике. Надеемся, вам было полезно! Успехов в написании кода!
Словари и их методы в Python
В краткой форме рассмотрим то, как устроены словари в языке Python, а также изучим некоторые методы для работы с ними. Чтение не займет больше 5 минут.
Что такое словарь
Словарь — неупорядоченная структура данных, которая позволяет хранить пары «ключ — значение». Вот пример словаря на Python:
dictionary =
Данный словарь использует строки в качестве ключей, однако ключом может являться в принципе любой неизменяемый тип данных. Значением же конкретного ключа может быть что угодно. Вот ещё один пример словаря, где ключами являются числа, а значениями — строки:
gender_dict =
Важное уточнение: если вы попробуете использовать изменяемый тип данных в качестве ключа, то получите ошибку:
dictionary =
Прим. перев. На самом деле проблема не с изменяемыми, а с нехэшируемыми типами данных, но обычно это одно и то же.
Получение данных из словаря
Для получения значения конкретного ключа используются квадратные скобки [] . Предположим, что в нашем словаре есть пара 'марафон': 26 .
# берём значение с ключом "марафон" dictionary['марафон']
Опять же, вы получите ошибку, если попытаетесь получить значение по несуществующему ключу. Для избежания подобных ошибок существуют методы, о которых мы сейчас поговорим.
Добавление и обновление ключей
Добавление новых пар в словарь происходит достаточно просто:
# Добавляем ключ "туфля" со значением "род обуви, закрывающей ногу не выше щиколотки" dictionary['туфля'] = 'род обуви, закрывающей ногу не выше щиколотки'
Обновление существующих значений происходит абсолютно также:
# Обновляем ключ "туфля" и присваиваем ему значение "хорошая туфля" dictionary['туфля'] = 'хорошая туфля'
Удаление ключей
Для удаления ключа и соответствующего значения из словаря можно использовать del
# Удаляем значение с ключом "противостоять" из словаря del dictionary['противостоять']
Методы
Словари в Python имеют множество различных полезных методов, которые помогут вам в работе с ними. Вот лишь некоторые из них:
Update
Метод update() пригодится, если нужно обновить несколько пар сразу. Метод принимает другой словарь в качестве аргумента.
# Добавляем две пары в словарь dictionary, используя метод update dictionary.update()
>>> dictionary
Если вас интересует, почему данные в словаре расположены не в том порядке, в котором они были внесены в него, то это потому что словари не упорядочены.
Get
# Допустим, у нас есть словарь story_count story_count =
Метод get() возвращает значение по указанному ключу. Если указанного ключа не существует, метод вернёт None .
# Ключ "двенадцать" существует и метод get в данном случае вернёт 12 story_count.get('двенадцать')
Метод можно использовать для проверки наличия ключей в словаре:
>>> story_count.get('два') None
Также можно указать значение по умолчанию, которое будет возвращено вместо None , если ключа в словаре не окажется:
# Метод вернёт 0 в случае, если данного ключа не существует story_count.get('два', 0)
Pop
Метод pop() удаляет ключ и возвращает соответствующее ему значение.
>>> story_count.pop('девяносто') 90 >>> story_count
Keys
Метод keys() возвращает коллекцию ключей в словаре.
>>> story_count.keys() ['сто', 'пять', 'двенадцать']
Values
Метод values() возвращает коллекцию значений в словаре.
>>> story_count.values() [100, 12, 5]
Items
Метод items() возвращает пары «ключ — значение».
>>> dictionary.items() [('персона', 'человек'), ('бежать', 'двигаться со скоростью'), ('туфля', 'род обуви, закрывающей ногу не выше щиколотки'), ('бежал', 'бежать в прошедшем времени'), ('марафон', 'гонка бегунов длиной около 26 миль'), ('туфли', 'туфля во множественном числе')]
Итерация через словарь
Вы можете провести итерацию по каждому ключу в словаре.
for key in story_count: print(key)
Очевидно, вместо story_count можно использовать story_count.keys() .
В примере кода ниже цикл for использует метод items() для получения пары «ключ — значение» на каждую итерацию.
>>> for key, value in dictionary.items(): print(key, value) ('персона', 'человек') ('бежать', 'двигаться со скоростью') ('туфля', 'род обуви, закрывающей ногу не выше щиколотки') ('бежал', 'бежать в прошедшем времени') ('марафон', 'гонка бегунов длиной около 26 миль') ('туфли', 'туфля во множественном числе')
О словаре и других типах данных Python можно почитать в нашей статье.
