#
7 set（集合）型 -- `set`, `frozenset`

set オブジェクトは順序付けされていない変更不可能な値のコレクションです。 よくある使い方には、メンバーシップのテスト、数列から重複を削除する、 そして論理積、論理和、差集合、対称差など数学的演算の計算が含まれます。 バージョン 2.4 で 新たに追加 された仕様です。

他のコレクションと同様、 setsは `x in set`、 `len(set)`および `for x in set` をサポートします。順序を持たないコレクションとして、setsは要素の位置と （要素の）挿入位置を保持しません。したがって、setsはインデックス、スライス、 その他のシーケンス的な振る舞いをサポートしません。

`set` および `frozenset`という、2つの組み込みset型があります。 `set` は変更可能な -- `add()` や `remove()`のような メソッドを使って内容を変更できます。変更可能なため、ハッシュ値を持たず、また 辞書のキーや他のsetの要素として用いることができません。`frozenset` 型は 変更不能であり、ハッシュ化可能で -- 一度作成されると内容を改変することが できません。一方で辞書のキーや他のsetの要素として用いることができます。

`set` および `frozenset` のインスタンスは、以下の演算を提供します。

Operation | Equivalent | Result
--- | --- | ---
`len(s)` |  | set s の基数

`x in s` |  | s のメンバに x があるか調べる
`x not in s` |  | s のメンバに x がないか調べる
`s.issubset(t)` | `s <= t` | t に s の全ての要素が含まれるか調べる
`s.issuperset(t)` | `s >= t` | s に t の全ての要素が含まれるか調べる

`s.union(t)` | s | t | s と tに含まれるすべての要素を持った新しいsetを作成
`s.intersection(t)` | s & t | s と t共通に含まれる要素を持った新しいsetを作成
`s.difference(t)` | s - t | s には含まれるが tには含まれない要素を持った新しいsetを作成
`s.symmetric_difference(t)` | s ^ t | s と tのうち、両者には含まれない要素を持った新しいsetを作成
`s.copy()` |  | sの浅いコピーを持った新しいsetを作成

注意すべき点として、演算子ではないバージョンのメソッド `union()`、 `intersection()`、+`difference()`、`symmetric_difference()`、 `issubset()`および `issuperset()`はどの種類のiterableでも引数として 受け入れます。対照的に、（それぞれのメソッドに）対応する演算子は引数にsetsを 要求します。これはより読みやすい`set('abc').intersection('cbs')` という構文を 優先して `set('abc') & 'cbs'` というような、エラーになりがちな構文を除外します。

`set` と `frozenset`の両者とも、setsとsetsの比較をサポートしています。 もし、あるいは少なくともそれぞれのsetsの全ての要素が他のsetsに含まれている （それぞれのsetsがもう片方のサブセットである）場合、2つのsetsは等しいと言えます。 もし、あるいは少なくとも1つめのsetが2つめのsetの厳密なサブセットである （サブセットではあるが等しくない）場合、setは他のsetより小さいと言えます。 もし、あるいは少なくとも1つめのsetが2つめのsetの厳密なスーパーセットである （スーパーセットではあるが等しくない）場合、setは他のsetより大きいと言えます。

`set` のインスタンスは`frozenset` のインスタンスと、そのメンバを基に 比較されます。例えば "`set('abc') == frozenset('abc')`" は `True`を返します。

サブセットと同一性の比較は完全な順序付け関数によって一般化されません。 例えば、どのような共通部分も持たない2つのsetsは、等しくもなく、互いのサブセットでもないので、 以下のコードの 全て に`False`を返します。 `a<b`、 `a==b`、 `a>b`。 それに応じて、setsは `__cmp__` メソッドを実装していません。

setsが部分的な順序付け（サブセットの関係）しか定義していないことから、 `list.sort()` メソッドの結果は不確定のsetsのリストとなります。

set の要素は辞書のキーと同様に `__hash__` と `__eq__` の 両方を定義していることが必要です。

`set` と`frozenset`のインスタンスを混在させたバイナリ演算は 結果を1つめのオペランドの型で返します。例えば "`frozenset('ab') | set('bc')`" は、`frozenset`のインスタンスを返します。

以下の表は`set`で可能なリスト操作です。これらの操作は変更不能な `frozenset` のインスタンスには適用されません。

Operation | Equivalent | Result
--- | --- | ---
`s.update(t)` | s |= t | set s を t の要素を追加して更新します
`s.intersection_update(t)` | s &= t | set s を s と t の両方に属する要素だけ残すように更新します
`s.difference_update(t)` | s -= t | set s を t に属する要素を削除するように更新します
`s.symmetric_difference_update(t)` | s ^= t | set s を s か t に属するが両方には属さない要素を持つように更新します

`s.add(x)` |  | set s に要素 x を追加します
`s.remove(x)` |  | set s から要素 x を削除します。要素が存在しない場合は `KeyError` を送出します
`s.discard(x)` |  | set s に要素 x が存在していれば削除します
`s.pop()` |  | s から、任意の要素を返してその要素を削除します。空の場合は `KeyError` を送出します
`s.clear()` |  | set s から全ての要素を削除します

注意すべき点として、演算子ではないバージョンのメソッド `update()`、 `intersection_update()`、 `difference_update()` および `symmetric_difference_update()` は、どんなiterableでも引数として 受け入れます。

set 型のデザインは `sets` で学んだことに基づいています。

参考:

Comparison to the built-in set types
  `sets` モジュールと組み込み set 型の違い