На этом шаге мы рассмотрим особенности использования этих типов данных.
Структура данных множество (set) - простейший тип коллекций в Python и многих других языках программирования. Многие популярные языки, предназначенные для распределенных вычислений (например, MapReduce и Apache Spark), практически исключительно сосредоточиваются на операциях с множествами как простыми типами данных. Что же такое множество? Множество - неупорядоченная коллекция уникальных элементов. Разобьем это определение на составные части.
Множество - коллекция элементов подобно спискам и кортежам. Коллекция состоит либо из элементов простых типов данных (целочисленных значений, значений с плавающей точкой, строковых значений), либо из более сложных элементов (объектов, кортежей). Однако все типы данных в множестве должны быть хешируемыми, то есть обладать соответствующим хеш-значением.
Хеш-значение объекта никогда не меняется и используется для его сравнения с другими объектами. Рассмотрим пример 1.8, где множество создается на основе трех строковых значений, после проверки их хеш-значений. Далее пробуем создать множество списков, но это нам не удается, поскольку списки нехешируемые.
hero = "Harry" guide = "Dumbledore" enemy = "Lord V." print(hash(hero)) # 6175908009919104006 print(hash(guide)) # -5197671124693729851 ## Можно ли создать множество строковых значений? characters = {hero, guide, enemy} print(characters) # {'Lord V.', 'Dumbledore', 'Harry'} ## Можно ли создать множество списков? team_1 = [hero, guide] team_2 = [enemy] teams = {team_1, team_2} # TypeError: unhashable type: 'list'
Множество строковых значений можно создать, поскольку строковые значения - хешируемые. А создать множество списков нельзя, поскольку списки нехешируемые. Дело в том, что хеш-значение зависит от содержимого элемента коллекции, а списки - изменяемые; если модифицировать данные в списке, то хеширование тоже должно измениться. А поскольку изменяемые типы данных нехешируемы, использовать их в множествах нельзя.
В отличие от списков, у элементов множества нет четко заданного порядка. Вне зависимости от очередности помещения данных в множество, никогда нельзя быть уверенным, в каком порядке они будут храниться в множестве. Вот пример:
characters = {hero, guide, enemy} print(characters) # {'Lord V.', 'Dumbledore', 'Harry'}
Мы вставили в множество сначала героя, но интерпретатор вывел первым антагониста (интерпретатор Python - явно на стороне зла). Учтите, что ваш интерпретатор может вывести элементы множества в другом порядке.
Все элементы множества должны быть уникальными. Строгое определение выглядит следующим образом: для всех пар значений x, y из множества при x != y хеш-значения также отличаются: hash(x) != hash(y). А поскольку все значения в множестве различны, создать армию Гарри Поттеров для войны с лордом В. не получится:
clone_army = {hero, hero, hero, hero, hero, enemy} print(clone_army) # {'Lord V.', 'Harry'}
Неважно, сколько раз вставляется одно значение в одно и то же множество, все равно в нем будет сохранен только один экземпляр этого значения. Дело в том, что у всех этих героев одно хеш-значение, а множество может содержать не более одного элемента с одинаковым хеш-значением. Существует расширение такой структуры данных , как множество, - мультимножество, в котором можно хранить несколько экземпляров одного значения. На практике, впрочем, оно используется редко. А обычные множества, напротив, встречаются практически в коде любого нетривиального проекта - например, для пересечения множества заказчиков и множества посетителей магазина, в результате чего будет возвращено новое множество заказчиков, которые также заходили в магазин.
На следующем шаге мы рассмотрим ассоциативные массивы.