web-dev-qa-db-ja.com

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

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が判断できないため、リストにセットを追加できないと思います。回避策はありますか?

編集:リストではなく要素を追加したい

189
Adam Matan

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

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

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

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

いくつかの事実:

  • 要素の設定および辞書キーはハッシュ可能でなければならない
  • ハッシュできないデータ型:
    • list:代わりにTupleを使用します
    • set:代わりにfrozensetを使用します
    • dict:公式の対応物はありませんが、いくつかあります recipes
  • オブジェクトインスタンスはデフォルトでハッシュ可能で、各インスタンスには一意のハッシュがあります。 Pythonリファレンスで説明されているように、この動作をオーバーライドできます。
156

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'}

編集:リストではなく、メンバーを追加する場合は、残念ながらタプルを使用する必要があります。セットメンバーは hashable でなければなりません。

425
aehlke

リストの要素をセットに追加するには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' when using built-in set function も参照してください。

65
JDiMatteo

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

>>> 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'])
39
alvas

関数set.update()に注意してください。ドキュメントには次のように書かれています:

セット自体と他のユニオンでセットを更新します。

14
eggfly

リストオブジェクトはハッシュ不可。ただし、タプルに変換することもできます。

8
SilentGhost

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

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

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

他の答えはすでにあなたにコードを与えています、私はこれが少し洞察を与えることを望みます。 Alex Martelliがさらに詳細に答えてくれることを期待しています。

5
user135331

リストではなく、タプルを追加します。

>>> 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')])

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

4
hughdbrown

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

とにかく、私が望んでいた動作は、idではなくhashを使用するように設定することでした。そのため、私が望んだ動作を提供するために、mydict[id(mylist)] = mylistではなくmyset.add(mylist)を見つけました。

3
Dunes

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

>>> 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')])
3
Noah

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

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