将列表添加到集合中

405

我如何将一系列数值添加到现有集合中?


7
你想要将列表添加到集合中还是将列表中的项添加到集合中? - pkit
1
列表本身 - 我想要一组列表。 - Adam Matan
2
似乎最合适的答案是被低估的那个,建议在将lst本身添加到某个列表/队列等之前使用aSet.add(id(lst)),以确保您只做了一次。您应该重新考虑接受的答案。 - Rustam A.
13个回答

904

向列表中添加内容

使用 set.update() 或者 |= 操作符:

>>> a = set('abc')
>>> a
{'a', 'b', 'c'}

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

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

将列表本身添加到集合中

直接将列表本身添加到集合中是不可能的,因为集合元素必须是可哈希的

相反,可以先将列表转换为元组:

>>> a = {('a', 'b', 'c')}

>>> xs = ['d', 'e']
>>> a.add(tuple(xs))
>>> a
{('a', 'b', 'c'), ('d', 'e')}

set.update()是将列表添加到集合中,对吗?那么管道等于运算符是用来做什么的? - FistOfFury
4
关于集合,运算符|执行并集操作|= 运算符和 set.update() 方法都是在原地应用该操作且实际上是等效的。因此,set_a |= set_b 可以视为 set_a.update(set_b)set_a = set_a | set_b 的语法糖(除了在后一种情况下,重复使用相同的set_a对象而不是重新赋值)。 - Cecil Curry

252

无法将列表添加到集合中,因为列表是可变的,这意味着您可以在将其添加到集合后更改列表内容。

但是,您可以将元组添加到集合中,因为您无法更改元组的内容:

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

编辑: 一些解释:文档将set定义为“无序但不重复的可哈希对象集合”。这些对象必须是可哈希的,以便在执行查找、添加和删除元素操作时比逐个查看每个元素更快。具体使用的算法在维基百科文章中有解释。Python 的哈希算法在effbot.org上有解释,而 Python 的 __hash__ 函数在python 参考手册中有解释。

一些事实:

  • 集合元素字典键必须是可哈希的
  • 一些不可哈希的数据类型:
    • list:使用tuple代替
    • set:使用frozenset代替
    • dict:没有官方对应物,但有一些解决方案
  • 对象实例默认情况下是可哈希的,每个实例都有一个唯一的哈希值。你可以按照 Python 参考手册中的说明覆盖此行为。

6
如果您想将一组元素添加到另一组元素中,可以使用frozenset。请注意,这里的翻译并不包含解释或其他内容。 - FogleBird
6
collections.namedtuple 可以被视为 dict 的“官方”对应物。 - SilentGhost
1
@Wahnfrieden:这是添加集合的内容,而不是集合本身。 - Otto Allmendinger
@aehlke:不,那样会将集合的元素添加到第一个集合中,但我们正在讨论将一个集合作为第一个集合的元素添加的情况。 - Jeff Learman
也许对于字典(dict)的情况,OrderedDictcollections库中可以使用? - Charlie Parker

98
使用update将列表的元素添加到集合中。
来自https://docs.python.org/2/library/sets.html

s.update(t):从t中返回添加到集合s的元素后的集合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


46

希望这能帮到你:

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

17
请注意函数set.update()。文档上写道:

使用自身和其他集合的并集更新一个集合。


6
这并未回答问题(因为原帖想要将列表本身添加到集合中),但当我通过谷歌搜索找到这里时,这正是我所需要的答案 :-) - tom stratton
2
嗯,对我来说这似乎是最相关的答案...例如,如果 b = set([1]),b.update([7,25]) 将给出 b 的以下值:set([1, 25, 7]) ---> 这不是我们在这里寻找的吗? - Louis LC

9

list对象是不可哈希的。虽然您可能希望将它们转换为元组。


7

集合不能有可变元素/成员。由于列表是可变的,因此不能成为集合的成员。

由于集合是可变的,因此您不能拥有一个集合的集合!但是,您可以拥有一个frozensets的集合。

(同样适用于字典的键的“可变性要求”.)

其他答案已经给出了代码,我希望这能提供一些见解。我希望Alex Martelli会回答更多细节。


6
我今天发现我需要做类似的事情。算法知道当它创建一个新列表并将其添加到集合中时,但不知道它何时完成对列表的操作。
无论如何,我想要的行为是集合使用id而不是hash。因此,我发现mydict[id(mylist)] = mylist可以提供我想要的行为,而不是myset.add(mylist)

5
您需要添加一个元组,而不是列表:
>>> 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

您需要使用元组,它们是可哈希的(无法哈希可变对象如列表)。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接