1. ホーム
  2. python

[解決済み] Pythonのセット操作における追加と更新の比較

2023-05-17 16:15:17

質問

Pythonでaddとupdateの操作の違いは何ですか?

a = set()
a.update([1]) #works
a.add(1) #works
a.update([1,2])#works
a.add([1,2])#fails 

なぜそうなるのか、誰か説明してください。

どのように解決するのですか?

set.add

set.add は個々の要素をセットに追加します。だから

>>> a = set()
>>> a.add(1)
>>> a
set([1])

は動作しますが、ハッシュ可能でない限り、イテラブルで動作することはできません。そのため a.add([1, 2]) が失敗する理由です。

>>> a.add([1, 2])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: unhashable type: 'list'

ここで [1, 2] はセットに追加される要素として扱われ、エラーメッセージにあるように a list cannot be hashed というエラーメッセージが出ますが、セットの要素はすべてハッシュ化可能であることが期待されます。を引用すると のドキュメントを引用します。 ,

新しい set または frozenset オブジェクトで、その要素は iterable から取得されます。集合の要素は必ず ハッシュ化可能 .

set.update

の場合 set.update の場合、複数のイテラブルを渡すと、すべてのイテラブルを繰り返し、個々の要素を集合に含めます。 覚えておいてください。 これは反復子のみを受け取ることができます。そのため、このメソッドに 1

>>> a.update(1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'int' object is not iterable

しかし、以下のようにすると、リスト [1] が反復され、リストの要素が集合に追加されるからです。

>>> a.update([1])
>>> a
set([1])

set.update は基本的にインプレース集合和集合操作と等価である。次のようなケースを考えてみましょう。

>>> set([1, 2]) | set([3, 4]) | set([1, 3])
set([1, 2, 3, 4])
>>> set([1, 2]) | set(range(3, 5)) | set(i for i in range(1, 5) if i % 2 == 1)
set([1, 2, 3, 4])

ここでは、すべての反復記号を明示的に集合に変換し、その和を求める。中間的な集合と結合は複数存在する。この場合 set.update は良いヘルパー関数として機能します。これは任意のイテラブルを受け付けるので、単純に次のようにすることができます。

>>> a.update([1, 2], range(3, 5), (i for i in range(1, 5) if i % 2 == 1))
>>> a
set([1, 2, 3, 4])