Рубрики
Без рубрики

Ultimate Guide к набору Python – с примерами Гарри Поттера

Эта статья дает вам все, что вам нужно знать о наборах в Python. Чтобы сделать его немного веселее, я использовал примеры Гарри Поттера по всей статье. Что такое набор Python? Установленная структура данных является одной из основных типов данных сбора в Python и многих других языках программирования. На самом деле, … Ultimate Guide To Python Sets – с примерами Harry Potter Подробнее »

Автор оригинала: Chris.

Эта статья дает вам все, что вам нужно знать о наборах в Python. Чтобы сделать его немного веселее, я использовал Примеры Гарри Поттера по всей статье.

Что такое набор Python?

Установленная структура данных является одной из основных типов данных сбора В Python и много других языков программирования.

На самом деле, есть даже популярные языки для распределенных вычислений, которые фокусируются практически исключительно на заданных операциях (например, MapReduce или Apache Spark) в качестве примитивов языка программирования.

Определение: Набор является неупорядоченной коллекцией уникальных элементов.

Давайте сломаемся.

(1) Коллекция : Набор – это коллекция элементов, таких как список или кортеж. Сборник состоит из примитивных элементов (например, целых чисел, поплавков, струн) или сложных элементов (например объекты, кортежи). Тем не менее, все типы данных должны быть засажены.

Что такое Hasable тип данных?

Вот соответствующий выдержка документации:

«Объект усугубляется, если он имеет значение HASH, которое никогда не меняется в течение его жизни (ему нужно __hash __ () Способ) и можно сравнить с другими объектами (это требует метода __eq __ () или __cmp __ ()). “

Установленная структура данных в значительной степени зависит от хеш-функции для реализации спецификации.

Давайте посмотрим на пример (мы остаемся с примерами Гарри Поттера, потому что это на вершине моего ума – чтение его каждый день с моей дочерью)

hero = "Harry"
guide = "Dumbledore"
enemy = "Lord V."

print(hash(hero))
# 6175908009919104006

print(hash(guide))
# -5197671124693729851

## Puzzle: can we create a set of strings?

characters = {hero, guide, enemy}
print(characters)
# {'Lord V.', 'Dumbledore', 'Harry'}


## Puzzle: can we create a set of lists?
team_1 = [hero, guide]
team_2 = [enemy]

teams = {team_1, team_2}
# TypeError: unhashable type: 'list'

Как видите, мы можем создать набор строк, потому что строки одновременно одновременно. Но мы не можем создать набор списков, потому что списки неходятся.

Почему перечислены в списках?

Потому что они смены: вы можете изменить список по Приобретая или Удаление элементы. Если вы измените тип данных списка, изменяется значение HASH (вычисляется на основе содержания списка). Это непосредственно нарушает вышеуказанное определение ( «Hash Value […] Никогда не меняется в течение его жизни» ).

Ключ на вынос: Соребительные типы данных не являются одновременными. Поэтому вы не можете использовать их в наборах.

(2) Неупорядоченные : В отличие от списков, наборы неупорядочены, потому что нет фиксированного порядка элементов. Другими словами, независимо от Заказать Вы положите вещи в набор, вы никогда не можете быть уверены, в каком порядке набор хранит эти элементы.

Вот пример из вышеуказанного кода:

characters = {hero, guide, enemy}
print(characters)
# {'Lord V.', 'Dumbledore', 'Harry'}

Вы сначала положили героя, но переводчик печатает врага сначала (переводчик Python находится на темной стороне, очевидно, что).

(3) Уникальный : Все элементы в комплекте уникальны. Каждая пара значений (x, y) в комплекте создает другую пару хеш-значений (y)). Следовательно, каждая пара элементов X и Y в наборе разные.

Это означает, что мы не можем создать армию Гарри Поттера клонов, чтобы бороться с лордом V:

clone_army = {hero, hero, hero, hero, hero, enemy}
print(clone_army)
# {'Lord V.', 'Harry'}

Независимо от того, как часто вы помещаете то же значение в тот же набор, набор хранит только один экземпляр этого значения. Расширение нормальной установки структуры данных является Структура данных “MultiSet” где MultiSet может хранить несколько экземпляров того же значения.

Стандартная библиотека Python также поставляется с MultiSet Package Отказ

Как создать набор?

Есть три основных альтернатива для создания набора:

  1. Используйте конструктор Установить ([1,2,3]) и пройти итеративное из элементов;
  2. Используйте нотацию кронштейна {1,2,3} с элементами внутри, разделенных запятой; или
  3. Создайте пустой набор и добавьте элементы вручную.

Вот пример этих трех вариантов:

s1 = {"Harry", "Ron", "Hermine"}
print(s1)
# {'Harry', 'Ron', 'Hermine'}

s2 = set(["Harry", "Ron", "Hermine"])
print(s2)
# {'Harry', 'Ron', 'Hermine'}

s3 = set()
s3.add("Harry")
s3.add("Ron")
s3.add("Hermine")
print(s3)
# {'Harry', 'Ron', 'Hermine'}

Однако вы не можете смешивать эти способы создать набор! Например, вы не можете передать отдельные элементы в конструкторе Установить () Отказ

# Wrong!
s4 = set("Harry", "Ron", "Hermine")
# TypeError: set expected at most 1 arguments, got 3

Один вопрос, который часто спрашивает, является следующим:

Можно ли установить несколько типов данных?

Да, конечно! Вот что произойдет, если вы создаете набор с целыми числами и строками:

s = {1, 2, 3, "Harry", "Ron"}
print(s)
# {1, 2, 3, 'Ron', 'Harry'}

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

Что такое реальные примеры наборов?

Наборы везде в кодировке. Каждый основной язык программирования поставляется со встроенным заданным функционалом. Установленная структура данных является одной из самых важных структур данных. Вы будете использовать это все время!

Например, вы пишете веб-сканет, который исследует веб-страницы и сохраняет свой URL в переменной «посещенном». Теперь есть два способа реализации этого: во-первых, используйте структуру данных списка и добавить URL, если это не в список. Во-вторых, используйте установленную структуру данных и добавьте URL, если он не находится в наборе. Второй путь быстрее! Почему? Поскольку наборы предназначены для очень быстро, чтобы проверить членство в отдельных элементах (например, URL уже в комплекте?). Прочитайте последнюю часть этой статьи, чтобы узнать, почему!

Другой пример в маркетинге электронной почты. Предположим, у вас есть огромная база данных абонентов электронной почты, хранится в виде списка. Вы хотите найти дубликаты адресов электронной почты. Легко: преобразовать список на набор и обратно в список – и VOILà – дубликаты исчезли! Почему? Поскольку наборы являются дублирующими. Кстати, это также один из самых быстрых способов удаления дубликатов из списка.

[Обзор] Каковы наиболее важные набор операций в Python?

Все Установить методы называются данными Установить Отказ Например, если вы создали набор s = {1, 2, 3} Вы бы назвали S.CLEAR () Чтобы удалить все элементы набора. Мы используем термин «Этот набор» обратиться к множеству, на котором выполняется метод.

Добавить() Добавьте элемент на этот набор
Чисто() Удалите все элементы из этого набора
Копировать () Создать и вернуть плоскую копию этого набора
разница() Создайте и верните новый набор, содержащий все элементы этого набора, кроме те, которые в данных аргументах. Полученный набор имеет максимум как много элементов, как этот набор.
Разница_update () Удалите все элементы из этого набора, которые являются членами любого из заданных аргументов.
отказаться() Удалите элемент из этого набора, если он является членом, иначе ничего не сделайте.
Пересечение () Создайте и верните новый набор, который содержит все элементы, которые являются членами всех наборов – это и установочный аргумент, а также.
Intersection_Update () Удаляет все элементы из этого набора, которые не являются членами во всех других указанных наборах.
iSdisjoint () Верните true, если ни один элемент из этого набора не является членом любого другого указанного набора. Наборы пересекаются, если и только если их пересечение – это пустой набор.
issubset ( Верните True, если все элементы этого набора являются членами указанного набора аргумента.
ОСУПЕРСЕТ () Верните true, если все элементы указанного набора аргумента являются членами этого набора.
поп () Удалить и вернуть случайный элемент из этого набора. Если набор пуст, он поднимет брелок.
Удалить() Удалите и верните определенный элемент из этого набора, как определено в аргументе. Если набор не содержит элемента, он поднимет keyError.
Symmetric_difference () Верните новый набор с элементами в этом наборе или указанном наборе аргумента, но не элементы, которые являются членами обоих.
Symmetric_difference_update () Замените этот набор с помощью симметричной разницы, то есть элементы в этом наборе или указанном наборе аргумента, но не элементы, которые являются членами обоих.
Союз () Создайте и верните новый набор со всеми элементами, которые находятся в этом наборе или в любом из указанных настроек аргументов.
Обновить() Обновите этот набор со всеми элементами, которые находятся в этом наборе, или в любом из указанных настроек аргументов. Полученный набор имеет по меньшей мере, как и любой другой элементы.

Вы можете скачать набор методов в кратком PDF здесь:

Давайте сначала начнем с нескольких примеров. Возьмите свое время, чтобы изучить эти примеры тщательно.

Gryffindors = {"Harry", "Ron", "Hermine", "Neville",
               "Seamus", "Ginny", "Fred", "George"}

## Set Conversion
Weasleys = set(["Ron", "Ginny", "Fred"])
# {'Ron', 'Fred', 'Ginny'}

## Add Element
Weasleys.add("George")
# {'Ron', 'Fred', 'Ginny', 'George'}

## Remove Element
Gryffindors.remove("Neville")
# {'Ron', 'Hermine', 'George', 'Harry', 'Ginny', 'Seamus', 'Fred'}

## Membership
'Ginny' in Gryffindors
# True

## Size
len(Weasleys)
# 4

## Intersection
Weasleys & Gryffindors
# {'Fred', 'George', 'Ron', 'Ginny'}

## Union
Weasleys | Gryffindors
# {'Ron', 'Hermine', 'George', 'Harry', 'Ginny', 'Seamus', 'Fred'}

## Difference
Gryffindors - Weasleys
# {'Harry', 'Hermine', 'Seamus'}

## Symmetric Difference
Gryffindors ^ {'Harry', 'Ginny', 'Malfoy'}
# {'Ron', 'Fred', 'George', 'Malfoy', 'Hermine', 'Seamus'}

## Set Disjoint
Gryffindors.isdisjoint({'Malfoy', 'Grabbe', 'Goyle'})
# True

## Subset
Weasleys.issubset(Gryffindors)
# True

## Superset
Gryffindors.issuperset(Weasleys)

## Pop
print(Gryffindors.pop())
# 'Seamus'
print(Gryffindors)
# {'Ron', 'Fred', 'Hermine', 'Harry', 'Seamus', 'George'}

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

Как установить преобразование работы в Python?

Наборы – это коллекции, такие как кортежи или списки. Вот почему вы можете легко преобразовать множества в списках или кортежах. Вот как:

# convert list to set:
s = set([1,2,3])
print(s)
# {1, 2, 3}

# convert tuple to set:
s = set((1,2,3))
print(s)
# {1, 2, 3}

Обратите внимание, что интерпретатор Python использует нотацию кронштейна для представления набора на вашей консоли.

Как добавить элемент на набор в Python?

Используйте функцию набора S.ADD (X) Чтобы добавить элемент х на множество s . Вот пример:

# Add Operator
s = set()
s.add("Harry")
s.add("Ron")
s.add("Hermine")
print(s)
# {'Harry', 'Ron', 'Hermine'}

Как удалить элемент из набора в Python?

Используйте функцию набора S.Remove (X) Чтобы удалить элемент х от набора S Отказ Обратите внимание, что из-за того, что набор не является дублирующимся, нельзя, что элемент х все еще существует в наборе после звонка Удалить () Отказ Таким образом, семантика отличается от списков Python, где Удалить () Удаляет только первое вхождение элемента в списке.

Вот пример:

# Remove Operator
s = set()
s.add("Harry")
s.add("Ron")
s.add("Hermine")
print(s)
# {'Harry', 'Ron', 'Hermine'}

s.remove("Ron")
s.remove("Harry")
print(s)
# {'Hermine'}

Как проверить, находится ли элемент в наборе в Python (членство)?

Оператор членства “х в s” Проверяет ли набор S Содержит элемент х Отказ Это возвращает Правда Если это так. Вот пример:

# Membership Operator
s = {"Harry", "Ron", "Hermine"}
x = "Ginny"
print(x in s)
# False

Как определить количество элементов в наборе Python?

Просто используйте встроенный ЛЕН (S) Функция, чтобы получить количество элементов в комплекте s .

Вот пример:

# Size Operator
s = {"Harry", "Ron", "Hermine"}
print(len(s))
# 3

Как пересекать два набора в Python?

Набор Пересечение Оператор создает новый набор, который содержит все элементы, которые находятся в обоих наборах S1 и S2 – Но не те, которые являются только в одном наборе. Это означает, что новый набор никогда не будет больше, чем любой из наборов S1 или S2.

В Python есть два оператора для пересекания двух наборов S1 и S2: метод S1.Internersection (S2) или оператор S1 & S2 Отказ

Может быть, вы помните диаграммы Venn из школы? Вот пример Установить Пересечение:

Как видите, новый набор содержит все элементы, которые находятся в обоих наборах S1 и S2 Отказ

Вот пример в коде:

# Intersection
good = {"Harry", "Ron", "Snape"}
bad = {"Lord V", "Quirrell", "Snape"}

print(good & bad)
# {'Snape'}

print(good.intersection(bad))
# {'Snape'}

Что такое союз двух наборов?

Установить Union Operator Создает новый набор, который содержит все элементы, которые находятся в любом наборе S1 или S2 Отказ Это означает, что новый набор никогда не будет меньше, чем любой из наборов S1 или S2 Отказ

В Python есть два оператора, чтобы рассчитать союз двух наборов S1 или S2 : Функция S1.union (S2) или оператор S1 |. S2 Отказ

# Union
good = {"Harry", "Ron", "Snape"}
bad = {"Lord V", "Quirrell", "Snape"}

print(good | bad)
# {'Lord V', 'Quirrell', 'Snape', 'Harry', 'Ron'}

print(good.union(bad))
# {'Lord V', 'Quirrell', 'Snape', 'Harry', 'Ron'}

В чем разница между двумя наборами?

Установить разницу оператора Создает новый набор, который содержит все элементы, которые находятся в наборе S1 Но не в S2 Отказ Это означает, что новый набор никогда не будет больше, чем Set S1 Отказ

В Python есть два оператора для расчета разности двух наборов S1 или S2 : метод s1.difference (S2) или оператор S1 – S2.

# Difference
good = {"Harry", "Ron", "Snape"}
bad = {"Lord V", "Quirrell", "Snape"}

print(good - bad)
# {'Harry', 'Ron'}

print(good.difference(bad))
# {'Harry', 'Ron'}

Какова симметричная разница двух наборов?

Симметричная установка разницы Оператор создает новый набор, который содержит все элементы, которые находятся в любом месте S1 или в S2 Но не в пересечении S1 или S2 Отказ

# Symmetric Difference
good = {"Harry", "Ron", "Snape"}
bad = {"Lord V", "Quirrell", "Snape"}

print(good ^ bad)
# {'Quirrell', 'Ron', 'Harry', 'Lord V'}

print(good.symmetric_difference(bad))
# {'Quirrell', 'Ron', 'Harry', 'Lord V'}

print(bad.symmetric_difference(good))
# {'Quirrell', 'Ron', 'Lord V', 'Harry'}

Что такое набор непересекающийся оператор в Python?

Установка непересекающихся операций проверяет два задания, не имеют ли у них элементов общего.

# Set Disjoint Operation
good = {"Harry", "Ron", "Snape"}
bad = {"Lord V", "Quirrell", "Snape"}

print(good.isdisjoint(bad))
# False

print(bad.isdisjoint(good))
# False

bad.remove("Snape")
print(good.isdisjoint("Snape"))
# True

Как видите, хорошее и плохое в Гарри Поттере не пересекают, потому что «Снейп» – это хорошо и плохо. Однако после удаления «Снейпа» от множества плохих волшебников (оповещение о спойлере) они снова несерьезно.

Как работает оператор подмножества в Python?

Операция s1.issubset (S2) В Python проверяет ли все элементы набор S1 также элементы в наборе S2 Отказ Конечно, набор S2 может иметь гораздо больше элементов, которые не в наборе S1 Отказ

# Set Subset Operation
Gryffindors = {"Seamus", "Fred", "George", "Harry", "Ginny", "Hermine"}
Weasleys = {"Fred", "George", "Ginny"}

print(Weasleys.issubset(Gryffindors))
# True

print(Gryffindors.issubset(Weasleys))
# False

Хотя набор всех Weasleys представляет собой подмножество множества всех гриффиндоров, наоборот не держит – есть (еще) гриффиндеров, которые не являются Weasleys (например, «Гарри» и «Гермин»).

Как работает оператор SuperSet в Python?

Операция s1.issuperset (S2) В Python аналогично предыдущей операции issubset () Отказ Но в отличие от этого, он проверяет ли все элементы набор S2 также элементы в наборе S1 Отказ Конечно, набор S1 может иметь гораздо больше элементов, которые не в наборе S2 Отказ

# Set Superset Operation
Gryffindors = {"Seamus", "Fred", "George", "Harry", "Ginny", "Hermine"}
Weasleys = {"Fred", "George", "Ginny"}

print(Weasleys.issuperset(Gryffindors))
# False

print(Gryffindors.issuperset(Weasleys))
# True

Очевидно, что множество всех островов не является суперсом набора всех гриффиндоров (например, «Гарри» не является Уизли). Тем не менее, набор всех гриффиндоров – суперсета набора всех островов.

Как поп-набор элемент в Python?

S.POP () Операция удаляет произвольный элемент х от набора s . Это возвращает этот элемент х Отказ POP () Операция часто полезна, потому что вы не можете легко получить доступ к произвольному элементу набора – вы не можете использовать индексы на наборах Python, потому что наборы неупорядочены.

Вот пример:

# Set Pop Operation
teachers = {"Trelawney", "Snape", "Hagrid"}
leaves_hogwarts = teachers.pop()
print(teachers)
# e.g. {'Snape', 'Hagrid'}

Помните, когда проф. Умбридж контролировал каждого учителя в Хогвартс? Она быстро узнала, что профессор Трелокни не является подходящим учителем, поэтому она выгнала ее из набора всех учителей. По сути, она выполнила POP () Операция (хотя выбирая элемент из набора был менее случайным).

Как работает набор пониманий?

Установка понимания – это краткий способ создания наборов. Скажем, вы хотите отфильтровать всех клиентов из вашей базы данных, которые зарабатывают более 1 000 000 долларов. Это то, что новичок, не знающий набора, будет делать:

# (name, $-income)
customers = [("John", 240000),
            ("Alice", 120000),
            ("Ann", 1100000),
            ("Zach", 44000)]
# your high-value customers earning >$1M
whales = set()
for customer, income in customers:
   if income>1000000:
       whales.add(customer)
print(whales)
# {'Ann'}

Этот фрагмент нуждается в четырех строках, чтобы создать набор высококачественных клиентов (китов)!

Если вы сделаете это в вашей общедоступной основе Python Code Code, будьте готовы получить выгоду для «не написания кода Pythonic». 😉

Вместо этого гораздо лучший способ сделать то же самое – использовать установленное понимание:

whales = {x for x,y in customers if y>1000000}
print(whales)
# {'Ann'}

Красивая, не так ли?

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

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

Другими словами, вот формула для заданного понимания.

Формула: Установленное понимание состоит из двух частей.

'{' + expression + context + '}'

Первая часть – выражение Отказ В приведенном выше примере это была переменная х. Но вы также можете использовать более сложное выражение, такое как X.upper (). Используйте любую переменную в своем выражении, которую вы определены в контексте в операторе петли. Смотрите этот пример:

whales = {x.upper() for x,y in customers if y>1000000}
print(whales)
# {'ANN'}

Вторая часть – контекст Отказ Контекст состоит из произвольного числа для и если положения. Одна цель контекста – определить (или ограничить) последовательность элементов, на которых мы хотим применить выражение. Вот почему вы иногда видите сложные ограничения, такие как это:

small_fishes = {x + str(y) for x,y in customers if y<1000000 if x!='John'}
# (John is not a small fish...)
print(small_fishes)
# {'Zach44000', 'Alice120000'}

Для получения более подробной информации о заданном понимании прочитайте эту статью.

Python устанавливает VS списков – когда использовать наборы и когда списки в Python?

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

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

Это золотой стандарт.

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

Давайте посмотрим на практический пример: проблема снятия дубликатов из коллекции.

dupes = [1,4,3,2,3,3,2,1]

# Bad solution: wrong data structure (list)
lst_tmp = [ ]
for element in dupes:
    if element not in lst_tmp:
        lst_tmp.append(element)
print(lst_tmp)
# [1, 4, 3, 2]


# Good solution: right data structure (set)
print(list(set(dupes)))
# [1, 2, 3, 4]

Вы используете установленную структуру данных здесь из-за своих специфических характеристик: набор является неупорядоченным собранием уникальных элементов. Бинго! Это то, что нам нужно.

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

Почему список неэффективен в этом примере? Поскольку проверка членства очень медленно для списков – вам нужно перейти весь список, чтобы увидеть, находится ли элемент в списке или нет.

Итак, как вы знаете, когда использовать списки и когда использовать наборы в Python?

Просто помните следующую упрощенную таблицу.

Вместо того, чтобы использовать более сложный нотацию Big-O, я просто скажу вам, является ли операция быстро или медленная (для профессионалов: быстрая – это постоянная сложность времени выполнения, медленная – это линейная сложность времени выполнения). Если вы хотите погрузиться глубже в сложности выполнения разных заданных операций, пожалуйста, смотрите вторую более полную таблицу ниже.

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

# Оператор Список Установленный
Добавить элемент БЫСТРО БЫСТРО
Удалить элемент МЕДЛЕННЫЙ БЫСТРО
Членство («в») МЕДЛЕННЫЙ БЫСТРО
Доступ i-й элемент БЫСТРО
Союз МЕДЛЕННЫЙ
Пересечение МЕДЛЕННЫЙ

По просто английскому языку: Используйте наборы, если вам нужно только тестировать для членов, использовать списки, если порядок элементов важен.

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

Как установлена структура данных в Python? А зачем устанавливать членство быстрее, чем в списке членов?

Мы уже установили:

” Список членства медленнее, чем устанавливать членство, потому что первые проверяют каждый элемент, когда последний использует только один поиск ».

Вы действительно понимаете, почему?

Если я обращаю эту тему в моем электронном виде Python курс (это бесплатно, присоединяйтесь ко мне 😉, подходит следующий вопрос:

«Я до сих пор не понимаю, почему установить проверки членства должны быть быстрее. Почему это только один поиск для набора? »

Я считаю, что многие современные кодера будут иметь трудности, объясняющие, почему установить членство быстрее. Приостановите чтение на мгновение и попытайтесь объяснить это себе!

Так, Как наборы работают в Python?

Наборы реализованы с помощью хэш-таблица в качестве базовой структуры данных. Хэш-таблица – это структура данных, которая отображает ключи к значениям (как дикт в Python). Вот пример хэш-столового, хранящегося в возрасте случайный «Гарри Поттер»:

Key --> Value
(Name) --> (Age)
----------------
"Harry" --> 13
"Hermine" --> 13
"Dumbledore" --> 398
"Lord V" --> 72

Прежде чем двигаться дальше, как Python использует хэш-таблица для реализации набора? Просто с помощью «фиктивных значений». Вот как python, концептуально, реализует набор {«Гарри», «Гермин», «Дамблдор», «Господь V»} :

"Harry" --> None
"Hermine" --> None
"Dumbledore" --> None
"Lord V" --> None

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

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

Помните, наша цель – это следующее. Учитывая ключ, мы хотим получить соответствующее значение (например, «Гарри» должен дать нам значение «13»).

В основе любого хэш-таблица – это массив. Предположим, мы храним данные в массиве, как это:

Index --> Value
0 --> ("Harry", 13)
1 --> ("Hermine", 13)
2 --> ("Dumbledore", 398)
3 --> ("Lord V", 72)

Это на самом деле, сколько хеш-таблиц реализовано (например, на языке программирования C). Хорошая вещь с массивами в том, что если вы знаете индекс, вы можете быстро получить пару (ключ, значение), сохраненную в этом индексе. Например, вы можете получить (ключ, значение) -PAIR («Лорд V», 72) в один быстрый выстрел, позвонив Массив [3] Отказ

Тем не менее, тестирование, существует ли определенный ключ в массиве, это боль: вы должны проверить каждый элемент массива, пока вы либо не найдут ключ, либо вы не запустите элементы массива. Если массив имеет размер n, вам нужно поиск N Элементы, если ключ не находится в массиве.

Хэш-таблица использует хороший трюк: он использует функцию, которая отображает ключ к индексу (называется функцией HASH). Затем индекс используется для получения соответствующего значения в массиве. Если вы посмотрите на него сверху, вы назначаете ключи от значений.

Прочитайте последний абзац снова, пока не получите его.

Вот пример:

Key --> Hashing --> Index --> Value
"Harry" --> h("Harry") --> 0 --> 13
"Hermine" --> h("Hermine") --> 1 --> 13
"Dumbledore" --> h("Dumbledore") --> 2 --> 398
"Lord V" --> h("Lord V") --> 3 --> 72

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

Теперь вот дело: независимо от того, сколько у вас есть (ключ, стоимость) пар, вы рассчитываете индекс с помощью хеш-функции на клавише и используете индекс для доступа к элементу массива (значение). Оба вычисления значения хеша и доступа к массиву быстро и независимо от размера структуры данных.

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

Куда пойти отсюда?

Если вам понравилось узнать о основах Python, вы будете любить мой бесплатный «Coffe Break Python» серии электронной почты.

Нажмите на ссылку, поместите свой адрес электронной почты и насладитесь 5 чис-листами Python и сотни небольших ежедневных лекций Python в вашем почтовом ящике.

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

Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python одноклассники (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.

Его страсти пишут, чтение и кодирование. Но его величайшая страсть состоит в том, чтобы служить стремлению кодер через Finxter и помогать им повысить свои навыки. Вы можете присоединиться к его бесплатной академии электронной почты здесь.

Оригинал: “https://blog.finxter.com/sets-in-python/”