設定するリストを追加しますか?


242

Python 2.6インタープリターでテスト済み:

>>> a=set('abcde')
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> l=['f','g']
>>> l
['f', 'g']
>>> a.add(l)
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    a.add(l)
TypeError: list objects are unhashable

同じリストを2回追加したかどうかをPythonが判断できないため、リストにセットを追加できないと思います。回避策はありますか?

編集:その要素ではなく、リスト自体を追加したいと思います。


2
セットまたはリスト内のアイテムにリストを追加しますか?
pkit 2009

リスト自体-リストのセットが必要です。
Adam

最も適切な答えは過小評価されたものであるようです。リスト/キューなどにlst自体を追加する前にaSet.add(id(lst))を使用して、確実に実行したことを確認することをお勧めします。受け入れられた回答を再検討する必要があります。
ロスタムA.

回答:


187

リストは変更可能であるため、セットにリストを追加することはできません。つまり、セットに追加した後でリストの内容を変更できます。

ただし、タプルの内容は変更できないため、セットにタプルを追加できます。

>>> a.add(('f', 'g'))
>>> print a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

編集:いくつかの説明:ドキュメントでは、setハッシュ可能な個別のオブジェクトの順序付けられいないコレクションとして定義しています。これらの操作を実行するたびに個々の要素を確認するよりも速く要素を検索、追加、および削除できるように、オブジェクトはハッシュ可能でなければなりません。使用される特定のアルゴリズムは、ウィキペディアの記事で説明されています。Pythonハッシュアルゴリズムについては、Pythonリファレンスのeffbot.orgおよびpythons__hash__関数で説明されています

いくつかの事実:

  • セット要素辞書キーはハッシュ可能でなければなりません
  • 一部のハッシュ化できないデータ型:
    • listtuple代わりに使用
    • setfrozenset代わりに使用
    • dict:公式の対応はありませんが、いくつかのレシピがあり ます
  • オブジェクトインスタンスはデフォルトでハッシュ可能であり、各インスタンスには一意のハッシュがあります。pythonリファレンスで説明されているように、この動作をオーバーライドできます。

6
また、セットにセットを追加する場合は、frozensetを使用します。
FogleBird 2009

4
collections.namedtupleの「公式」版と見なされる可能性がありますdict
SilentGhost 2009

1
@Wahnfrieden:これは、セット自体ではなく、セットの内容を追加しています。
Otto Allmendinger

@aehlke:いいえ、それはセットの要素を最初のセットに追加しますが、ここではセットを最初のセットの要素として追加することについて話しています。
ジェフリアマン2018年

578

set.update()またはを使用|=

>>> a = set('abc')
>>> l = ['d', 'e']
>>> a.update(l)
>>> a
{'e', 'b', 'c', 'd', 'a'}

>>> l = ['f', 'g']
>>> a |= set(l)
>>> a
{'e', 'b', 'f', 'c', 'd', 'g', 'a'}

編集:メンバーではなくリスト自体を追加する場合は、残念ながらタプルを使用する必要があります。セットのメンバーはハッシュ可能である必要があります。


set.update()はリストをセットに追加しますよね?pipe equals演算子とは何ですか?
FistOfFury

セットに関しては、|オペレーターはセットユニオン操作を実装します|=演算子とset.update()メソッドの両方がその操作をインプレースで適用し、実質的に同義です。だから、set_a |= set_b両方のための糖衣構文と考えられるset_a.update(set_b) set_a = set_a | set_b(後者の場合には、同じことを除いてset_aオブジェクトを再利用ではなく、再割り当てされています)。</ahem>
セシルカレー

76

するために、セットにリストの要素を追加し、使用update

https://docs.python.org/2/library/sets.htmlから

s.update(t):tから追加された要素を持つセットsを返す

例えば

>>> s = set([1, 2])
>>> l = [3, 4]
>>> s.update(l)
>>> s
{1, 2, 3, 4}

代わりに、リスト全体を単一の要素としてセットに追加する場合は、リストをハッシュできないため、追加できません。代わりにタプルを追加することもできs.add(tuple(l))ます。TypeError:unhashable type: 'list'もご覧ください。


40

うまくいけば、これが役立ちます:

>>> seta = set('1234')
>>> listb = ['a','b','c']
>>> seta.union(listb)
set(['a', 'c', 'b', '1', '3', '2', '4'])
>>> seta
set(['1', '3', '2', '4'])
>>> seta = seta.union(listb)
>>> seta
set(['a', 'c', 'b', '1', '3', '2', '4'])

15

機能にご注意くださいset.update()。ドキュメントは言う:

自分自身と他のユーザーの結合でセットを更新します。


5
これは質問には答えません(OPはリスト自体をセットに追加したいためです)が、Googleがここに連れてきたときに私が必要とした答えでした:-)
tom stratton

1
まあ、それは私への質問に対する最も関連性の高い答えのようです...たとえば、b = set([1])の場合、b.update([7,25])はbに次の値を与えます:set([ 1、25、7])--->ここで探しているのではないですか?
Louis LC


5

セットは、変更可能な(変更可能な)要素/メンバーを持つことはできません。変更可能なリストは、セットのメンバーにすることはできません。

セットは変更可能であるため、セットのセットを持つことはできません!ただし、frozensetのセットを持つことができます。

(同じ種類の「可変性の要件」は、dictのキーに適用されます。)

他の回答ですでにコードが提供されています。これが少し洞察を与えることを願っています。Alex Martelliがさらに詳細に回答してくれることを期待しています。


4

リストではなくタプルを追加したい場合:

>>> a=set('abcde')
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> l=['f','g']
>>> l
['f', 'g']
>>> t = tuple(l)
>>> t
('f', 'g')
>>> a.add(t)
>>> a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

リストがある場合は、上記のようにタプルに変換できます。タプルは不変なので、セットに追加できます。


4

今日も同じようなことをする必要があることに気づきました。アルゴリズムは、セットに追加する必要のある新しいリストを作成しているときは知っていましたが、リストの操作が終了するときは知りませんでした。

とにかく、私が欲しかった動作はset idではなくを使用することhashでした。そのため、私が望んでいた振る舞いを提供するmydict[id(mylist)] = mylist代わりに私は見つけましたmyset.add(mylist)


3

あなたはハッシュ可能なタプルを使いたいでしょう(リストのような可変オブジェクトをハッシュすることはできません)。

>>> a = set("abcde")
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> t = ('f', 'g')
>>> a.add(t)
>>> a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

2

これが私が通常行う方法です:

def add_list_to_set(my_list, my_set):
    [my_set.add(each) for each in my_list]
return my_set

-4

これは行う必要があります:

set(tuple(i) for i in L)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.