Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

pythonの集合型 set

pythonの集合型setの使い方について。
 
・重複のない配列。
・順序がないのでs[1]のようなインデックス指定ができない。
・inメソッドによる検索が高速
 
○生成

# coding: utf-8

s1 = set()          # 空のset
print(s1)           # set()
print(type(s1))     # <class 'set'>

s2 = {1, 1, 2, 2, 3, 4}
print(s2)           # {1, 2, 3, 4}
print(len(s2))      # 4 要素数

s3 = {}
print(type(s3))     # <class 'dict'>     
     
list1 = [1, 3, 5, 7]
s4 = set(list1)
print(s4)           # {1, 3, 5, 7}

t = (2, 4, 6, 8)
s5 = set(t)
print(s5)           # {8, 2, 4, 6} 順序は保証されない

d = {"a":1, "b":5}
s6 = set(d)
print(s6)           # {'a', 'b'} キーのみの集合

s7 = set("akasaka") # 文字列からsetを生成
print(s7)           # {'s', 'a', 'k'}

s1 = {1, 3, 5}
s8 = s1.copy()
print(s8)           # {1, 3, 5}

 
○追加

s1 = {1, 3, 5}
s1.add(7)            # 要素7を追加
print(s1)            # {1, 3, 5, 7}

s1.add(1)            # すでに存在する要素を追加しても変更なし
print(s1)            # {1, 3, 5, 7}

s1 = {1, 3, 5}
list1 =[10, 20, 30]
s1.update(list1)     # listを追加
print(s1)            # {1, 3, 5, 10, 20, 30}

s1 = {1, 2, 3}
#s1.update(7, 8, 9)  # TypeError: 'int' object is not iterable
s1.update((7, 8, 9)) # タプルの追加は括弧が必要
print(s1)            # {1, 2, 3, 7, 8, 9}

s1 = {1, 2, 3}
s2 = {4, 5, 6}
d ={7:7, 8:8}
s1.update(s2, d)     # 複数のタプル、リスト、辞書、集合の追加ができる
print(s1)            # {1, 2, 3, 4, 5, 6, 7, 8}

 
○削除

s1 = {1, 3, 5}
s1.remove(5)       # 要素5を削除
print(s1)          # {1, 3}

#s1.remove(4)      # KeyError: 4 存在しない要素はエラー

s1.discard(4)      # 存在しなくてもエラーなし
s1.discard(3)      # 要素3を削除
print(s1)          # (1)

s1 = {1, 3, 5}
s1.pop()           # ランダムで削除
print(s1)          # {3, 5}

s1 = {1, 3, 5}
p = s1.pop()       # ランダムで削除し、その要素をpに代入
print(p)           # 1
          
s1 = {1, 2, 3, 4, 5}
s2 = {0, 1, 2, 3}
s3 = s1 - s2       # s1の要素からs2の要素を引く
print(s3)          # {4, 5}

s1 = {1, 2, 3, 4, 5}
s2 = {0, 1, 2, 3}
s3 = s1.difference(s2)  # s1 - s2と同義だが、set型以外でも。
print(s3)          # {4, 5}
#s4 = s1 + s2      # TypeError: unsupported operand type(s) for +: 'set' and 'set'

 
○全削除

s1 = {1, 3, 5}
s1.clear()     # 要素を全削除
print(s1)      # set()

del s1         # 変数s1を削除
#print(s1)     # NameError: name 's1' is not defined

 
○和集合

s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1 | s2             # 和集合
print(s3)                # {1, ,2 ,3, 5}
         
s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1.union(s2)        # s1 | s2 と同義で、set以外でも。
print(s3)                # {1, ,2 ,3, 5}

 
○積集合

s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1 & s2             #共通部分(積集合)
print(s3)                # {1, 3}
         
s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1.intersection(s2) # s1 & s2 と同義で、set以外でも。
print(s3)                # {1, 3}

 
○一方のみ

s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1 ^ s2             # elements in s1 or s2 but not both
print(s3)                # {2, 5}
         
s1 = {1, 3, 5}
s2 = {1, 2, 3}
s3 = s1.symmetric_difference(s2)   # s1 ^ s2 と同義で、set以外でも。
print(s3)                          # {2, 5}

 
○累積演算ができる
s1 |= s2
s1 &= s2
s1 -= s2
s1 |= s2

s1 = {1, 3, 5}
s2 = {1, 2, 3}
s1 &= s2
print(s1)       # {1, 3}

 
○検索
in 含まれていたらTrue
not in 含まれていなかったらTrue

s1 = {1, 3, 5}
print(1 in s1)     # True
print(2 in s1)     # False
print(3 not in s1) # False
print(4 not in s1) # True

 
○部分集合

s1 = {1, 3, 5}
s2 = {1, 3}
s3 = {1, 2}

print(s1 >= s2) # True
print(s1 >= s1) # True
print(s1 > s1)  # False
print(s1 <= s2) # False
print(s3 <= s1) # False

print(s1.issubset(s2))   # print(s1 <= s2) と同義
print(s1.issuperset(s2)) # print(s1 >= s2) と同義

 
○set内包表記

a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)   # {'r', 'd'}

 

すべての部分集合の列挙

集合型で作る方法がわからなかったので、itertoolsで。

# 全ての部分集合の列挙
from itertools import combinations

items = [1, 2, 3, 4]
subsets=[]
for i in range(len(items) + 1):
    for c in combinations(items, i):
        subsets.append(c)

print(subsets)      # [(), (1,), (2,), (3,), (4,), (1, 2), ..., (2, 3, 4), (1, 2, 3, 4)]
print(len(subsets)) # 16

 
・frozensetについてはまたそのうち
 
参考:
pythonドキュメント データ構造