セット#
教科書 p.155(Lesson 6.5)セットは並び順のないデータの集合を表すコレクションです。
セットは波括弧 {} で囲み、リストに格納する各データ(要素)はカンマ , で区切ります。
セットの値は重複させることはできず、順序もありません。
>>> kinki_prefs = { "京都", "大阪", "兵庫", "奈良", "滋賀", "和歌山", "三重" }
>>> kinki_prefs # 内容を表示する。大概の場合、上記の順序と違っている。
{'京都', '三重', '和歌山', '大阪', '兵庫', '奈良', '滋賀'} # 順番はこの通りではないかもしれません。
>>> fibonacci = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 } # 重複する値は無視される。
>>> fibonacci
{1, 2, 3, 34, 5, 8, 13, 21, 55} # 1が重複していたため、1つだけになっている。セットの操作#
セットへの追加/削除#
セットの要素は、追加/削除が可能です。
セットへの要素の追加はセット名.add(値)、削除はセット名.remove(値) を用います。
セットの値が重複する場合は、値は追加されません。
また、要素数はlen関数を用いて取得します。
>>> primes = {1, 3, 5, 7, 11, 13, 17 }
>>> primes # 表示順序はこの通りではないかもしれない。
{1, 17, 3, 5, 7, 11, 13}
>>> primes.remove(1) # 1 は素数ではなかった!
>>> primes # 1 が削除されている。
{17, 3, 5, 7, 11, 13}
>>> primes.remove(4) # 存在しない値を削除しようとするとエラーが発生する。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 4
>>> primes.add(19) # 19を追加する。
>>> primes
{17, 3, 19, 5, 7, 11, 13}
>>> primes.add(19) # 19は既に存在するので追加されない。
>>> primes
{17, 3, 19, 5, 7, 11, 13}
>>> len(primes) # 要素数を取得する。
7要素の確認#
セットに特定の要素が含まれているかどうかを調べるには、in演算子を用います。
含まれている場合はTrue、含まれていない場合はFalseが返されます。
>>> primes = {1, 3, 5, 7, 11, 13, 17 }
>>> 3 in primes
True
>>> 4 in primes
Falseセットの演算#
教科書 p.157(Lesson 6.5)セットに対してのみ有効な演算子があり、和集合、積集合、差集合、対称差集合を求めることができます。
演算子と同等の機能を持つメソッドも用意されています。
演算子を用いる場合、値1 演算子 値2 という形で記述し、被演算子(値1、値2の両方)はセットである必要があります。
一方、メソッドを用いる場合は、値1.メソッド(値2)という形で記述します。
メソッドの場合は、値1はセットである必要がありますが、値2は必ずしもセットである必要はなく、イテラブル(繰り返しできる値)であればよいです。
加えて、どちらの場合も、演算結果は新たなセットとして返されます。
| 演算 | 演算子 | メソッド | 説明 |
|---|---|---|---|
| 和集合 | | | union | 2つの集合の要素を全て含む集合。 |
| 積集合 | & | intersection | 両方の集合に含まれる要素のみを含む集合。 |
| 差集合 | - | difference | ある集合に含まれる要素を除いた集合。 |
| 対象差 | ^ | symmetric_difference | どちらかの集合にのみ含まれる要素をもつ集合。 |
>>> s1 = {1, 3, 5, 7, 9}
>>> s2 = {2, 3, 5, 7, 11}
>>> s1 | s2 # 和集合
{1, 2, 3, 5, 7, 9, 11}
>>> s1 & s2 # 積集合
{3, 5, 7}
>>> s1 - s2 # 差集合
{1, 9}
>>> s2 - s1 # 差集合。演算順序を変えると異なる結果になる。
{2, 11}
>>> s1 ^ s2 # 対称差集合
{1, 2, 9, 11}
>>> s1.union(s2) # 和集合(メソッド)
{1, 2, 3, 5, 7, 9, 11}
>>> s1.intersection(s2) # 積集合(メソッド)
{3, 5, 7}
>>> s1.difference(s2) # 差集合(メソッド)
{1, 9}
>>> s2.difference(s1) # 差集合(メソッド)。
{2, 11}
>>> s1.symmetric_difference(s2) # 対称差集合
{1, 2, 9, 11}セットの繰り返し#
セットはイテラブル(繰り返し可能なオブジェクト)であるため、for文を用いて繰り返し処理を行うことができます。
ただし、セットは順序を持たないため、繰り返しで特定の順番で要素を取得することを期待してはいけません。
>>> s = {1, 3, 5, 7, 11, 13, 17 }
>>> for x in s:
... print(x)
1
17
3
5
7
11
13やってみよう: 2 つの名簿を比べる#
セットの演算を使って、2 つの名簿を比べるプログラムを members.py という名前で書いてください。
講義 A と講義 B の受講者の名簿がリストで与えられます。
lecture_a = ["佐藤", "鈴木", "高橋", "田中", "伊藤", "渡辺", "山本", "田中"]
lecture_b = ["田中", "中村", "小林", "加藤", "鈴木", "吉田", "山本"]このリストから、次の 4 つを求めて表示してください。 まず 2 つのリストをセットに変換し、あとは セットの演算 を使うだけです。 講義 A の名簿には「田中」が 2 回出てきますが、セットに変換すると重複は消えます。
- 両方の講義を受けている人
- 講義 A だけを受けている人
- 講義 B だけを受けている人
- どちらかの講義を受けている人(重複なし)の人数
実行結果は次のようになります(セットは順番を持たないので、名前の並び順は違っていて構いません)。
両方: {'鈴木', '田中', '山本'}
A だけ: {'佐藤', '高橋', '伊藤', '渡辺'}
B だけ: {'中村', '小林', '加藤', '吉田'}
どちらか: 11 人🏁 解答例
lecture_a = ["佐藤", "鈴木", "高橋", "田中", "伊藤", "渡辺", "山本", "田中"]
lecture_b = ["田中", "中村", "小林", "加藤", "鈴木", "吉田", "山本"]
set_a = set(lecture_a) # リストをセットに変換する。重複していた「田中」は 1 つになる。
set_b = set(lecture_b)
print("両方:", set_a & set_b) # 積集合
print("A だけ:", set_a - set_b) # 差集合
print("B だけ:", set_b - set_a) # 差集合(順序を入れ替える)
print("どちらか:", len(set_a | set_b), "人") # 和集合の要素数