Руководство по словарям Python

Словари и инструменты для работы с данными Python

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

В этом руководстве мы рассмотрим следующие темы:

  • как создать словарь, используя фигурные скобки и двоеточия;
  • как загрузить данные в словарь с помощью библиотек urllib и random;
  • как фильтровать словарь с помощью цикла for и специальных итераторов для перебора ключей и значений словаря;
  • как выполнять операции со словарем для получения или удаления значений, и как использовать значения словаря для подмножества значений из него;
  • как сортировать словарь с помощью библиотеки re и как в этом могут помочь функции OrderedDict и лямбда-функции;
  • сравним словари Python со списками, массивами NumPy и Pandas DataFrames.

Как создать словарь Python

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

Словари можно распознать по фигурным скобкам {} и разделению двоеточием : ключа и значения для каждого элемента.

Переменная fruit в приведенном ниже коде является допустимым словарем. Получить доступ к элементу Python словаря можно, поместив ключ между квадратными скобками [].Также можно использовать метод .get(), чтобы сделать то же самое:

fruit = {"apple" : 5, "pear" : 3, "banana" : 4, "pineapple" : 1,https://www.datacamp.com/community/tutorials/python-dictionary-tutorial "cherry" : 20}
# Получаем доступ к словарю `fruit` непосредственно (без использования get) и выводим значение "banana"
print(_____["______"])
# Выбираем один из 5 фруктов и показываем, что оба способа извлечения дают аналогичные результаты
print(fruit["_____"] == fruit.get("_____"))

Загрузка данных в словарь Python

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

Используемые данные - это отзывы на Amazon о книге Донны Тартт "The Goldfinch". Они были сохранены в простом файле с разделителями. Таблица содержит четыре столбца: оценка, URL-адрес, заголовок отзыва и текст отзыва.

Есть несколько способов представить эти данные в Python словаре, но в нашем случае мы берем URL-адрес в качестве ключа и помещаем другие столбцы в словарь с вложенными значениями:

import urllib
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] 
  id = l[1]
  title = l[2]
  review = l[3]

  reviews[id] = {"score" : score, "title" : title, "review" : review}
# Берем случайный ключ из словаря и выводим его значение

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

# Подсчитываем количество строк в файле
print("Количество строк: " + str(len(lines)))
# Подсчитываем количество ключей в словаре; оно должно равняться количеству строк в файле
print("Количество ключей словаря: " + str(len(reviews.keys())))

Как отфильтровать словарь Python

Теперь, когда отзывы хранятся в словаре, пришло время попробовать выполнить некоторые операции. Допустим, вы хотите посмотреть, что на самом деле написали люди, выбрав только отзывы с оценкой 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: # Convert score to float
    lowscores.append(key)
# Выводим все записи с низкой оценкой
for item in __________:
  print(reviews[____])

Операции над словарями Python

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

Во-первых, мы используем ключи, хранящиеся в lowscores, для создания нового словаря. Чтобы сделать это, есть два способа: первый - извлекаем только соответствующие элементы из исходного словаря с помощью метода .get(), оставляя исходный словарь без изменений. Второй - использовать метод .pop(), который удаляет извлеченные записи из исходного словаря.

Код для подмножества может выглядеть следующим образом: subset = dict([(k, reviews.get(k)) for k in lowscores]). Такое написание может показаться незнакомым, потому что цикл задан одной строкой кода. Этот стиль называется «генерацией словаря». На самом деле это цикл for, который перебирает элементы lowscores, извлекает значения из отзывов и использует их для заполнения нового словаря.

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

# Метод с использованием цикла for для создания подмножества словаря
forloop = {}
for k in lowscores:
  forloop[k] = reviews[k]
# Добавляем специальный метод извлечения релевантных элементов из словаря `reviews`
dictcomp = {k : reviews.___(k) for k in lowscores}
# Удостоверимся, что эти объекты аналогичны
print(forloop == ________)

Предположим, что теперь вы хотите изменить словарь Python 3, чтобы оценки выступали в качестве ключей словаря, а не идентификаторов. Можно использовать для этого цикл for, указав как ключи, так и значения, и создав новый вложенный словарь. Нужно будет извлечь "score" из исходного вложенного словаря, чтобы использовать его в качестве нового ключа.

Чтобы упростить код, мы создаем в отдельной строке новый вложенный словарь как новый объект newvalues. После чего заполняем scoredict идентификаторами в качестве ключей и объектами из словаря newvalues в качестве значений:

from collections import defaultdict
scoredict = defaultdict(list)
for key, value in reviews.items():
  newvalues = {'id' : key, "title" : value['title'], "review" : value['review']}
  # Используем 'score' из значений (!) из исходного словаря в качестве ключей для только что созданного  словаря
  scoredict[_____['_____']].append(newvalues)

# Выводим ключи словаря, чтобы удостовериться, что это на самом деле оценки из отзывов
print(scoredict.keys())

Как сортировать словари на Python

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

Нам нужно немного обработать текст отзывов, удалив HTML-теги и конвертировав заглавные буквы в словах в нижний регистр. Для первой задачи мы используем регулярное выражение, которое удаляет все теги: re.sub("", ""). Регулярные выражения - это полезный инструмент при работе с текстовыми данными. Они довольно сложны для компиляции и заслуживают отдельного руководства.

Но в нашем примере нужно просто определить наборы символов, которые начинаются с символа <, за которым следует произвольное количество символов, после чего стоит символ >. И заменить их на пустые кавычки "" (ничего).

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

Затем мы создаем частотный словарь, используя defaultdict вместо обычного словаря. Это гарантирует, что каждый «ключ» уже инициализирован, и можно просто увеличивать его частоту, начиная с 1.

Если вы не используете defaultdict, Python может выдать ошибку при первом увеличении частоты (с 0 до 1), потому что ключ еще не существует. Этого можно избежать, предварительно проверив, существует ли ключ в Python словаре, прежде чем увеличивать значение его частоты. Но это решение не такое элегантное, как defaultdict:

import re
# Импортируем defaultdict
from collections import ___________
freqdict = defaultdict(int)
for item in lowscores:
  review = reviews[item]["review"]
  cleantext = re.sub(r'<.*?>', '', review).strip().split() # Remove HTML tags and split the review by word (space separated)
  for word in cleantext:
   # Конвертируем все буквы в нижний регистр
    word = word.lower()

    # Заполняем следующую строку, чтобы увеличить частоту на один:
    freqdict[word] += _

print(freqdict)

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

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

Второй аргумент указывает, какую часть первого аргумента следует использовать для сортировки: key=lambda item: item[1]. Но вам придется более углубленно изучить язык Python, чтобы понять, что это такое. Первая часть довольно понятна: вы хотите, чтобы ключи сортировались.

Но что там делает lambda? Она является анонимной функцией, то есть это функция без имени, которая не может быть вызвана извне. Это альтернативный способ обработки через цикл целого ряда объектов с помощью одной функции. В данном случае используется значение словаря (item[1], при item[0] выступающем в качестве ключа) в качестве аргумента для сортировки.

Третий (последний) аргумент, reverse, указывает, должна ли сортировка выполняться по возрастанию (по умолчанию) или по убыванию. В данном случае мы хотим увидеть наиболее часто встречающиеся слова вверху и указываем reverse=True.

Прямо сейчас вы были бы разочарованы словами, которые располагаются в самом верху списка отсортированных элементов. Это были бы просто «функциональные слова», такие как «the», «and», «a» и т. д. В английском, как и во многих других языках, эти слова употребляются достаточно часто. Но при этом они совершенно бессмысленны сами по себе.

В текстовой аналитике для удаления этих высокочастотных слов используются так называемые стоп-листы. Мы же применим более примитивный подход, игнорируя верхние 10% слов и рассматривая только слова, которые относятся к остальным 90%. Вы увидите, что в верхней части списка представлены как слова с негативным оттенком, такие как «неинтересно» и «разочаровывающе», так и более позитивные: «увлекательно» и «чудесно».

Можно поэкспериментировать и посмотреть, в каких частях Python словаря можно найти интересные слова:

from collections import OrderedDict
# Создаем словарь Ordered
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])

Сравнение словарей со списками Python, массивами NumPy и Pandas DataFrames

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

Такие библиотеки, как Pandas, позволяют обработчикам данных работать быстрее и эффективнее. Им больше не нужно беспокоиться о деталях более низкого уровня, касающихся того, как хранятся данные. Но Pandas также использует словари (наряду с другими расширенными структурами данных, такими как массив NumPy) для хранения данных.

Даже при применении Pandas иногда рекомендуется использовать словари. Например, когда значения необходимо просто сопоставить, и вам не нужны функции Pandas ни для чего другого. Использование объекта Pandas в таких случаях просто неэффективно и излишне.

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

Перевод статьи «Python Dictionary Tutorial» дружной командой проекта Сайтостроение от А до Я.

04 мая 2017 в 14:41
Материалы по теме
{"url":"http://www.fastvps.ru/", "src":"/images/advbanners/fastvps.png", "alt":"Хостинг Fastvps.ru. Наш выбор!"}
Заработок