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)