понедельник, 7 декабря 2015 г.

Тип данных множества (set и frozenset)

Множества (общие понятия)



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


Множество - это некий набор элементов, как правило, сгруппированный по каким-то признакам, хотя это может быть и беспорядочное множество, которое включает в себя просто набор чего-то. Кпримеру, куча ящиков - это множество ящиков, причем мы не уточняем, большие ящики, маленькие ящики и Т.Д. Это просто куча ящиков. Далее мы уточним, что у нас 3 ящика, В каждом из которых, находятся фрукты - яблоки, груши, бананы. Мы можем утверждать, что все эти фрукты, являются подмножеством множества ящиков. Это значит, что множество ящиков, включает в себя не только ящики, но и все подмножества, которые включают в себя ящики. Если мы уточняем, есть ли такой элемент как яблоко в нашем множестве ящиков, мы получаем утвердительный ответ. В нашем основном множестве, находятся 3 подмножества: ящик с грушами, ящик с яблоками, ящик с бананами. В каждом из этих ящиков, находятся подмножества соответствующих фруктов, но все эти фрукты, являются подмножествами множества ящиков. А вот если мы уточним, пренадлежит ли яблоко к множеству ящика с бананами, мы получим отрицательный ответ Т.К. Ящик с бананами и ящик с яблоками, являются раздельными множествами и никак не пересекаются, но в свою очередь, они являются подмножествами нашего множества ящиков. Если упростить этот пример еще больше, получим следующую картину: в магазине стоят три наших ящика с фруктами, в каждом ящике свой вид фруктов. Скажем, что магазин - это объемлющее множество, в которое входят ящики с фруктами. Если мы спросим, есть ли ящики в этом магазине? Мы получим утвердительный ответ, ведь ящики в действительности есть, они входят в множество "магазин". Если мы спросим, есть ли в этом магазине бананы? Мы опять получим утвердительный ответ Т.К. В магазине есть ящики и в одном из них есть бананы, значит множество бананов входит в множество не только их ящика, но и в множество магазина в котором находится подмножество ящика с бананами. А вот если мы покажем продавцу на ящик с яблоками и уточним, есть ли в нем бананы, мы получим отрицательный ответ, Т.К. Бананов в этом ящике нет. (Мы их можем туда положить, но это тема для более глубокого изучения множеств, как раздела дискретной математики).

Далее мы рассмотрим тип данных множества в Python И базовые действия над множествами.


Множество set



Множество в Python задается при помощи функции set():

>>> a = set([1,2,3,4,5])

>>> a

set([1, 2, 3, 4, 5])

>>>


Также есть упрощенная запись множества:



>>> b = {1,3,5}

>>> b

set([1, 3, 5])

>>>




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



>>> set([1,1,1,2,2,2,3,3,3,4])

set([1, 2, 3, 4])

>>>

>>> set("hello")

set(['h', 'e', 'l', 'o'])

>>>




Множество отвечает за наличие какого-то элемента в множестве, но не отвечает за то, сколько элементов может быть где-то в конкретном месте.

Мы можем преобразовывать списки, кортежи и строки в множества, а множества, в свою очередь, можем преобразовывать в списки и кортежи. Поскольку множества - итерируемые, их можно передавать непосредственно в цикл for:



>>> a

set([1, 2, 3, 4, 5])

>>> for i in a:

...     print i

...

1

2

3

4

5

>>>




В силу определенных причин, Python не умеет хранить множество в множестве, Т.Е. Реализовать пример (магазин>(ящик с бананами>(бананы), ящик с грушами>(груши), ящик с яблоками>(яблоки))), в одном множестве, которое делилось бы на множества и включало в себя все подмножества подмножеств, реализовать штатным типом данных невозможно. Это придется представлять отдельными объектами множеств, что немного изменяет математическую сущность множеств, но позволяет решать массу прикладных задач, которые не требуют строгого математического соответствия.


frozenset



Уже говорилось, что тип данных "set" изменяем, но также есть неизменяемый тип данных "frozenset". Они отличаются в той же степени, как и список отличается от кортежа.


Действия над множествами; Аспекты практического применения.



Рассмотрим простейшие действия над множествами в Python, а также частные случаи применения множеств для решения прикладных задач. Самое простое - это когда мы имеем список, который содержит в себе дублирующиеся элементы, а мы хотим избавится от них. Эта задача решается более чем простым способом:



>>> lst = ["a","c","b","c","c","d","g","d","e","a","g","f","b"]

>>> lst

['a', 'c', 'b', 'c', 'c', 'd', 'g', 'd', 'e', 'a', 'g', 'f', 'b']

>>> newlst = list(set(lst))

>>> newlst

['a', 'c', 'b', 'e', 'd', 'g', 'f']

>>>




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

Соединение множеств выполняется при помощи оператора "|". Предположим, что мы имеем 2 списка, которые нужно соединить таким образом, чтобы элементы не продублировались, воспользовавшись оператором соединения множеств и утверждениемо том, что множество не хранит в себе одинаковые элементы, выполняем следующую операцию:



>>> a = [1,2,4,5,7]

>>> b = [2,3,4,5,6,7,8,9]

>>> a

[1, 2, 4, 5, 7]

>>> b

[2, 3, 4, 5, 6, 7, 8, 9]

>>> set(a)|set(b)

set([1, 2, 3, 4, 5, 6, 7, 8, 9])

>>>




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



>>> a

[1, 2, 4, 5, 7]

>>> b

[2, 3, 4, 5, 6, 7, 8, 9]

>>> set(a)-set(b)

set([1])

>>>




Мы изъяли все существующие элементы множества "a", существующие в множестве "b", также и наоборот:



>>> set(b)-set(a)

set([8, 9, 3, 6])

>>>




Пересечение множеств, "&", позволяет вернуть элементы наборов данных, которые существуют во всех множествах:



>>> set(a)&set(b)

set([2, 4, 5, 7])

>>>




Симметричная разность множеств, "^", возвращает элементы, которые не пересекаются в переданных множествах:



>>> set(a)^set(b)

set([1, 3, 6, 8, 9])

>>>




На секунду, вспомним про оператор "in", который позволял узнать о наличии какого-то элемента в списке, кортеже или строке. Схожим образом, мы можем узнавать о наличии элементов одного множества в другом множестве. Фактически, мы спрашиваем о том, является ли одно множество, подмножеством другого:



>>> a = set([1,2,3,4,5,6,7,8,9]) # Множество натуральных чисел от 1 до 9

>>> b = set([3,4,5,6,7]) # множество натуральных чисел от 3 до 7

>>> c = set([3,5,7]) # множество чисел 3, 5 и 7

>>> a

set([1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> b

set([3, 4, 5, 6, 7])

>>> c

set([3, 5, 7])

>>>




Рассмотрим эти множества более внимательно. Множество "a", содержит в себе ряд чисел от 1 до 9, а множество "b", от 3 до 7. Множество "a", содержит в себе множество "b"? Естественно содержит, Т.К,. Все элементы множества "b", содержатся в множестве "a", а значит мы можем утверждать, что множество "b", является подмножеством множества "a". В свою очередь, множество "c", содержит в себе элементы 3, 5, и 7. Является ли множество "c", подмножеством множества "b"? Является, Т.К. Содержит в себе элементы, которые содержатся в множестве "b", а значит множество "c", является подмножеством множества "b", но в свою очередь оно является и подмножеством множества "a", Т.К. Множество "a", содержит в себе множество "b", подмножеством которого является множество "c", а мы уже говорили про то, что множество включает в себя все подмножества подмножеств, а это значит, что множество "c", является подмножеством множества "a".



>>> e = set([3,5,7,9,0])

>>> d

set([9, 3, 5, 7])

>>> e

set([0, 9, 3, 5, 7])

>>>




Попробуем проанализировать, множество "d", является подмножеством для одного из множеств a, b, c? Поскольку все элементы в множестве "d", встречаются только в множестве "a", оно является подмножеством множества "a". Является ли множество "e", подмножеством одного из множеств a,b,c,d? Нет, в множестве "e", встречается элемент "0", который отсутствует во всех множествах a, b, c, d. Но мы можем утверждать, что множества "c" и "d", являются подмножествами множества "e", а множество "c", подмножеством множества "d". Я думаю, что мы углубились в принципы множеств и подмножеств настолько глубоко, насколько позволяет данная тема и после этих примеров, принципы множеств должны быть более чем очевидны. Теперь рассмотрим операторы проверки на множество/подмножество. "<", спрашивает, является ли множество слева от оператора, подмножеством множества справа от оператора. Также и оператор ">", спрашивает о том, является ли множество справа от оператора, подмножеством множества слева от оператора:



>>> a

set([1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> b

set([3, 4, 5, 6, 7])

>>> a>b

True

>>> b>a # "a" не является подмножеством "b"

False

>>> b
True

>>> b

set([3, 4, 5, 6, 7])

>>> c

set([3, 5, 7])

>>> c>b

False

>>> b>c # "c" является подмножеством "b"

True

>>> a>c # "c" является подмножеством "a"

True

>>> a>b>c # c" является подмножеством "b" и "c", "b" является подмножеством "a"

True

>>>

>>> a

set([1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> c

set([3, 5, 7])

>>> d

set([9, 3, 5, 7])

>>> a>d>c

True

>>>



Методы объекта множества



set.isdisjoint(other) - истина, если set и other не имеют общих элементов.

set == other - все элементы set принадлежат other, все элементы other принадлежат set.

set.issubset(other) или set <= other - все элементы set принадлежат other.

set.issuperset(other) или set >= other - аналогично.

set.union(other, ...) или set | other | ... - объединение нескольких множеств.

set.intersection(other, ...) или set & other & ... - пересечение.

set.difference(other, ...) или set - other - ... - множество из всех элементов set, не принадлежащие ни одному из other.

set.symmetric_difference(other); set ^ other - множество из элементов, встречающихся в одном множестве, но не встречающиеся в обоих.

set.copy() - копия множества.

Операции, изменяющие объект множества:

set.update(other, ...); set |= other | ... - объединение.

set.intersection_update(other, ...); set &= other & ... - пересечение.

set.difference_update(other, ...); set -= other | ... - вычитание.

set.symmetric_difference_update(other); set ^= other - множество из элементов, встречающихся в одном множестве, но не встречающиеся в обоих.

set.add(elem) - добавляет элемент в множество.

set.remove(elem) - удаляет элемент из множества. KeyError, если такого элемента не существует.

set.discard(elem) - удаляет элемент, если он находится в множестве.

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

set.clear() - очистка множества.

Комментариев нет:

Отправить комментарий