8.7。 セット —ユニークな要素の順序付けられていないコレクション
バージョン2.3の新機能。
sets モジュールは、一意の要素の順序付けられていないコレクションを構築および操作するためのクラスを提供します。 一般的な用途には、メンバーシップテスト、シーケンスからの重複の削除、交差、和集合、差、対称差などのセットに対する標準的な数学演算の計算が含まれます。
他のコレクションと同様に、セットはx in set
、len(set)
、およびfor x in set
をサポートします。 順序付けられていないコレクションであるため、セットは要素の位置や挿入の順序を記録しません。 したがって、セットは、インデックス付け、スライス、またはその他のシーケンスのような動作をサポートしていません。
ほとんどのsetアプリケーションは、__hash__()
を除くすべてのsetメソッドを提供する Set クラスを使用します。 ハッシュメソッドを必要とする高度なアプリケーションの場合、 ImmutableSet クラスは__hash__()
メソッドを追加しますが、セットの内容を変更するメソッドを省略します。 Set と ImmutableSet はどちらも、BaseSet
から派生しています。これは、何かがセットであるかどうかを判断するのに役立つ抽象クラスisinstance(obj, BaseSet)
です。
セットクラスは、辞書を使用して実装されます。 したがって、セット要素の要件はディクショナリキーの要件と同じです。 つまり、要素は__eq__()
と__hash__()
の両方を定義します。 その結果、セットにリストや辞書などの可変要素を含めることはできません。 ただし、タプルや ImmutableSet のインスタンスなどの不変のコレクションを含めることができます。 セットのセットを実装する際の便宜のために、内部セットは自動的に不変の形式に変換されます。たとえば、Set([Set(['dog'])])
はSet([ImmutableSet(['dog'])])
に変換されます。
- class sets.Set([iterable])
- 新しい空の Set オブジェクトを作成します。 オプションの iterable パラメーターが指定されている場合、反復から取得された要素でセットを更新します。 iterable のすべての要素は、不変であるか、セクション不変への自動変換のプロトコルで説明されているプロトコルを使用して不変に変換可能である必要があります。
- class sets.ImmutableSet([iterable])
新しい空の ImmutableSet オブジェクトを作成します。 オプションの iterable パラメーターが指定されている場合、反復から取得された要素でセットを更新します。 iterable のすべての要素は、不変であるか、セクション不変への自動変換のプロトコルで説明されているプロトコルを使用して不変に変換可能である必要があります。
ImmutableSet オブジェクトは
__hash__()
メソッドを提供するため、セット要素または辞書キーとして使用できます。 ImmutableSet オブジェクトには要素を追加または削除するためのメソッドがないため、コンストラクターが呼び出されるときにすべての要素がわかっている必要があります。
8.7.1。 オブジェクトの設定
Set と ImmutableSet のインスタンスはどちらも、次の操作を提供します。
手術 | 同等 | 結果 |
---|---|---|
len(s)
|
セット内の要素の数 s (カーディナリティ) | |
x in s
|
s のメンバーシップについて x をテストします | |
x not in s
|
s の非メンバーシップについて x をテストします | |
s.issubset(t)
|
s <= t
|
s のすべての要素が t にあるかどうかをテストします |
s.issuperset(t)
|
s >= t
|
t のすべての要素が s にあるかどうかをテストします |
s.union(t)
|
t | s と t の両方の要素を含む新しいセット |
s.intersection(t)
|
s & t
|
s と t に共通の要素を持つ新しいセット |
s.difference(t)
|
s - t
|
s に要素が含まれているが、 t には含まれていない新しいセット |
s.symmetric_difference(t)
|
s ^ t
|
s または t のいずれか(両方ではない)の要素を持つ新しいセット |
s.copy()
|
s の浅いコピーを含む新しいセット |
union()
、intersection()
、difference()
、およびsymmetric_difference()
の非オペレーターバージョンは、引数として反復可能なものを受け入れることに注意してください。 対照的に、それらの演算子ベースの対応物は、それらの引数がセットである必要があります。 これにより、Set('abc') & 'cbs'
のようなエラーが発生しやすい構造が排除され、より読みやすいSet('abc').intersection('cbs')
が優先されます。
バージョン2.3.1で変更:以前はすべての引数を設定する必要がありました。
さらに、 Set と ImmutableSet の両方が、セット比較をサポートします。 2つのセットは、各セットのすべての要素が他の要素に含まれている場合にのみ等しくなります(それぞれが他のサブセットです)。 最初のセットが2番目のセットの適切なサブセットである場合(サブセットであるが等しくない場合)に限り、セットは別のセットよりも小さくなります。 最初のセットが2番目のセットの適切なスーパーセットである場合(スーパーセットですが、等しくない場合)に限り、セットは別のセットよりも大きくなります。
サブセットと同等性の比較は、完全な順序付け関数に一般化されていません。 たとえば、2つの互いに素なセットは等しくなく、互いにサブセットではないため、次の all はFalse
を返します:a<b
、a==b
、またはa>b
。 したがって、セットは__cmp__()
メソッドを実装していません。
セットは半順序(サブセット関係)のみを定義するため、list.sort()
メソッドの出力はセットのリストに対して未定義です。
次の表に、 ImmutableSet で使用できるが、 Set では見つからない操作を示します。
手術 | 結果 |
---|---|
hash(s)
|
s のハッシュ値を返します |
次の表に、 Set で使用できるが、 ImmutableSet では見つからない操作を示します。
手術 | 同等 | 結果 |
---|---|---|
s.update(t)
|
= t | t から要素が追加されたセット s を返します |
s.intersection_update(t)
|
NS &= NS | t にもある要素のみを保持するセット s を返します |
s.difference_update(t)
|
s -= t | t で見つかった要素を削除した後、セット s を返します |
s.symmetric_difference_update(t)
|
s ^ = t | s または t の要素を含むが、両方ではないセット s を返す |
s.add(x)
|
要素 x を追加して、 s を設定します | |
s.remove(x)
|
セット s から x を削除します。 存在しない場合はKeyError を発生させます
| |
s.discard(x)
|
存在する場合、セット s から x を削除します | |
s.pop()
|
s から任意の要素を削除して返します。 空の場合はKeyError を発生させます
| |
s.clear()
|
セット s からすべての要素を削除します |
update()
、intersection_update()
、difference_update()
、およびsymmetric_difference_update()
の非オペレーターバージョンは、引数として反復可能なものを受け入れることに注意してください。
バージョン2.3.1で変更:以前はすべての引数を設定する必要がありました。
また、このモジュールには、update()
のエイリアスであるunion_update()
メソッドも含まれていることに注意してください。 このメソッドは、下位互換性のために含まれています。 update()
メソッドを選択する必要があります。
8.7.2。 例
>>> from sets import Set
>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
>>> employees = engineers | programmers | managers # union
>>> engineering_management = engineers & managers # intersection
>>> fulltime_management = managers - engineers - programmers # difference
>>> engineers.add('Marvin') # add element
>>> print engineers
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
>>> employees.issuperset(engineers) # superset test
False
>>> employees.update(engineers) # update from another set
>>> employees.issuperset(engineers)
True
>>> for group in [engineers, programmers, managers, employees]:
... group.discard('Susan') # unconditionally remove element
... print group
...
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
Set(['Janice', 'Jack', 'Sam'])
Set(['Jane', 'Zack', 'Jack'])
Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack'])
8.7.3。 不変への自動変換のプロトコル
セットには、不変の要素のみを含めることができます。 便宜上、可変 Set オブジェクトはset要素として追加される前に ImmutableSet に自動的にコピーされます。
メカニズムは常に hashable 要素を追加することです。または、ハッシュ可能でない場合は、要素がチェックされ、不変の同等物を返す__as_immutable__()
メソッドがあるかどうかが確認されます。
Set オブジェクトには ImmutableSet のインスタンスを返す__as_immutable__()
メソッドがあるため、セットのセットを作成できます。
セットのメンバーシップをチェックするために要素をハッシュする必要がある__contains__()
およびremove()
メソッドでも、同様のメカニズムが必要です。 これらのメソッドは、要素のハッシュ可能性をチェックし、そうでない場合は、__hash__()
、__eq__()
の一時メソッドを提供するクラスによってラップされた要素を返す__as_temporarily_immutable__()
メソッドをチェックします。 __ne__()
。
代替メカニズムにより、元の可変オブジェクトの個別のコピーを作成する必要がなくなります。
Set オブジェクトは、新しいクラス_TemporarilyImmutableSet
によってラップされた Set オブジェクトを返す__as_temporarily_immutable__()
メソッドを実装します。
ハッシュ可能性を追加するための2つのメカニズムは、通常、ユーザーには見えません。 ただし、あるスレッドがセットを更新し、別のスレッドが一時的にセットを_TemporarilyImmutableSet
でラップしているマルチスレッド環境では、競合が発生する可能性があります。 言い換えると、可変セットのセットはスレッドセーフではありません。
8.7.4。 ビルトインとの比較設定タイプ
組み込みのセットおよびフローズンセットタイプは、セットモジュールから学んだ教訓に基づいて設計されました。 主な違いは次のとおりです。
- Set および ImmutableSet は set および frozenset に名前が変更されました。
BaseSet
に相当するものはありません。 代わりに、isinstance(x, (set, frozenset))
を使用してください。- 組み込みのハッシュアルゴリズムは、ほとんどのデータセットで大幅にパフォーマンスが向上します(衝突が少なくなります)。
- ビルトインバージョンには、よりスペース効率の良いピクルスがあります。
- 組み込みバージョンには、
union_update()
メソッドがありません。 代わりに、同等のupdate()
メソッドを使用してください。 - 組み込みバージョンには、
_repr(sorted=True)
メソッドがありません。 代わりに、組み込みの repr()および sorted()関数repr(sorted(s))
を使用してください。 - 組み込みバージョンには、不変に自動変換するためのプロトコルがありません。 多くの人がこの機能を混乱させると感じており、コミュニティの誰もそれの実際の使用法を見つけたと報告していません。