问题:添加列表进行设置?
在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无法告诉我是否两次添加了相同的列表。有解决方法吗?
编辑:我想添加列表本身,而不是其元素。
Tested on Python 2.6 interpreter:
>>> 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
I think that I can’t add the list to the set because there’s no way Python can tell If I have added the same list twice. Is there a workaround?
EDIT: I want to add the list itself, not its elements.
回答 0
您不能将列表添加到集合中,因为列表是可变的,这意味着您可以在将列表添加到集合后更改列表的内容。
但是,您可以将元组添加到集合中,因为您不能更改元组的内容:
>>> a.add(('f', 'g'))
>>> print a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])
编辑:某些解释:文档将a定义set
为不同的可哈希对象的无序集合。这些对象必须是可哈希化的,因此,与每次执行这些操作时都要查看每个单独的元素相比,查找,添加和删除元素可以更快地完成。Wikipedia文章中说明了使用的特定算法。在effbot.org上说明了Python的哈希算法,并且__hash__
在python参考中提供了pythons函数。
一些事实:
- 设置元素以及字典键必须是可哈希的
- 一些不可散列的数据类型:
list
:tuple
改用
set
:frozenset
改用
dict
:没有官方对应文件,但有一些
食谱
- 默认情况下,对象实例是可哈希的,每个实例具有唯一的哈希。您可以按照python参考中的说明覆盖此行为。
You can’t add a list to a set because lists are mutable, meaning that you can change the contents of the list after adding it to the set.
You can however add tuples to the set, because you cannot change the contents of a tuple:
>>> a.add(('f', 'g'))
>>> print a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])
Edit: some explanation: The documentation defines a set
as an unordered collection of distinct hashable objects. The objects have to be hashable so that finding, adding and removing elements can be done faster than looking at each individual element every time you perform these operations. The specific algorithms used are explained in the Wikipedia article. Pythons hashing algorithms are explained on effbot.org and pythons __hash__
function in the python reference.
Some facts:
- Set elements as well as dictionary keys have to be hashable
- Some unhashable datatypes:
list
: use tuple
instead
set
: use frozenset
instead
dict
: has no official counterpart, but there are some
recipes
- Object instances are hashable by default with each instance having a unique hash. You can override this behavior as explained in the python reference.
回答 1
使用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'}
编辑:如果要添加列表本身而不是其成员,那么很遗憾,您必须使用元组。集合成员必须是可哈希的。
Use set.update()
or |=
>>> 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'}
edit: If you want to add the list itself and not its members, then you must use a tuple, unfortunately. Set members must be hashable.
回答 2
回答 3
希望这会有所帮助:
>>> 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'])
Hopefully this helps:
>>> 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'])
回答 4
请注意该功能set.update()
。该文档说:
用本身和其他元素的并集更新集合。
Please notice the function set.update()
. The documentation says:
Update a set with the union of itself and others.
回答 5
list objects are unhashable. you might want to turn them in to tuples though.
回答 6
集合不能具有可变的(可变的)元素/成员。可变列表不能成为集合的成员。
由于集合是可变的,因此不能有集合!但是,您可以设置一组Frozensets。
(同一种“可变性要求”适用于字典的键。)
其他答案已经为您提供了代码,我希望这能提供一些见识。我希望Alex Martelli会提供更多详细信息。
Sets can’t have mutable (changeable) elements/members. A list, being mutable, cannot be a member of a set.
As sets are mutable, you cannot have a set of sets!
You can have a set of frozensets though.
(The same kind of “mutability requirement” applies to the keys of a dict.)
Other answers have already given you code, I hope this gives a bit of insight.
I’m hoping Alex Martelli will answer with even more details.
回答 7
您要添加一个元组,而不是列表:
>>> 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')])
如果有列表,则可以转换为元组,如上所示。元组是不可变的,因此可以将其添加到集合中。
You want to add a tuple, not a list:
>>> 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')])
If you have a list, you can convert to the tuple, as shown above. A tuple is immutable, so it can be added to the set.
回答 8
我发现我今天需要做类似的事情。该算法知道何时创建需要添加到集合中的新列表,但是不知道何时完成对列表的操作。
无论如何,我想要的行为是设置为使用id
而不是hash
。因此,我发现自己mydict[id(mylist)] = mylist
没有myset.add(mylist)
提供想要的行为。
I found I needed to do something similar today. The algorithm knew when it was creating a new list that needed to added to the set, but not when it would have finished operating on the list.
Anyway, the behaviour I wanted was for set to use id
rather than hash
. As such I found mydict[id(mylist)] = mylist
instead of myset.add(mylist)
to offer the behaviour I wanted.
回答 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')])
You’ll want to use tuples, which are hashable (you can’t hash a mutable object like a list).
>>> 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
这是我通常的做法:
def add_list_to_set(my_list, my_set):
[my_set.add(each) for each in my_list]
return my_set
Here is how I usually do it:
def add_list_to_set(my_list, my_set):
[my_set.add(each) for each in my_list]
return my_set
回答 11
应该这样做:
set(tuple(i) for i in L)
This should do:
set(tuple(i) for i in L)