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

Я думаю, что я не могу добавить список в набор, потому что не может сказать Python, если я дважды добавил тот же список. Есть ли способ обхода?

EDIT: я хочу добавить сам список, а не его элементы.

Ответ 1

Вы не можете добавить список в набор, потому что списки изменяемы, что означает, что вы можете изменить содержимое списка после добавления его в набор.

Однако вы можете добавить кортежи в набор, потому что вы не можете изменить содержимое кортежа:

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

Изменить: некоторое объяснение. Документация определяет set как неупорядоченный набор различных хешируемых объектов. Объекты должны быть хешируемыми, так что поиск, добавление и удаление элементов может выполняться быстрее, чем просмотр каждого отдельного элемента каждый раз, когда вы выполняете эти операции. Используемые конкретные алгоритмы объясняются в статье Википедии. Алгоритмы хэширования питонов объясняются в effbot.org и функции pythons __hash__ в ссылка на python.

Некоторые факты:

  • Установить элементы, а также словарные ключи должны быть хешируемыми
  • Некоторые нераспаковываемые типы данных:
    • list: используйте tuple вместо
    • set: используйте frozenset вместо
    • dict: нет официального партнера, но есть некоторые рецепты
  • Объектные экземпляры по умолчанию хешируются, каждый экземпляр имеет уникальный хеш. Вы можете переопределить это поведение, как описано в ссылке на python.

Ответ 2

Используйте 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'}

редактировать: если вы хотите добавить сам список, а не его членов, то, к сожалению, вы должны использовать кортеж. Набор участников должен быть хэшируемым.

Ответ 3

Чтобы добавить элементы списка в набор, используйте update

От https://docs.python.org/2/library/sets.html

s.update(t): возвращает set s с элементами, добавленными из t

например.

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

Если вы хотите добавить в список весь список как один элемент, вы не можете, потому что списки не хешируются. Вместо этого вы можете добавить кортеж, например. s.add(tuple(l)). См. Также TypeError: unhashable type: 'list' при использовании встроенной функции набора для получения дополнительной информации об этом.

Ответ 4

Надеюсь, это поможет:

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

Ответ 5

Обратите внимание на функцию set.update(). В документации указано:

Обновите набор с помощью объединения самого себя и других.

Ответ 6

объекты списка расстегнуты. вы можете включить их в кортежи.

Ответ 7

Наборы не могут иметь изменяемые (изменяемые) элементы/элементы. Список, являющийся изменяемым, не может быть членом набора.

Поскольку наборы изменяемы, у вас не может быть набора наборов! Однако у вас может быть набор фризонов.

(Тот же тип "требования к изменчивости" применяется к ключам dict.)

Другие ответы уже дали вам код, я надеюсь, что это дает немного понимания. Я надеюсь, что Алекс Мартелли ответит еще более подробно.

Ответ 8

Вы хотите добавить кортеж, а не список:

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

Если у вас есть список, вы можете преобразовать его в кортеж, как показано выше. Кортеж неизменен, поэтому его можно добавить в набор.

Ответ 9

Вы хотите использовать кортежи, которые являются хешируемыми (вы не можете хешировать изменяемый объект, например список).

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

Ответ 10

Я обнаружил, что мне нужно сегодня сделать что-то подобное. Алгоритм знал, когда он создавал новый список, который нужно было добавить в набор, но не тогда, когда он закончил работу в списке.

Во всяком случае, поведение, которое я хотел, было для set использовать id, а не hash. Как таковой я нашел mydict[id(mylist)] = mylist вместо myset.add(mylist), чтобы предложить поведение, которое я хотел.

Ответ 11

Вот как я обычно это делаю:

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

Ответ 12

Это должно сделать:

set(tuple(i) for i in L)