在python的set操作中添加vs更新


71

如果我只想向集合中添加单个值,则python中的添加和更新操作之间有什么区别?

a = set()
a.update([1]) #works
a.add(1) #works
a.update([1,2])#works
a.add([1,2])#fails 

有人可以解释为什么会这样。


1
您正在使用哪个版本的Python?对于a.update(1)TypeError: 'int' object is not iterable来说,我尝试过的两个版本都可以得到它。
史蒂夫·杰索普

1
@thefoutheye,您的编辑相当程度上改变了这个问题
Padraic Cunningham


1
@PadraicCunningham我们都知道它不会起作用。我们可以同意这只是复制/粘贴错误吗?如果没有,请随时恢复我的修订:)
thefourtheye

1
@thefoureye是的,这是我末端的复制粘贴错误
aceminer

Answers:


96

set.add

set.add向集合中添加单个元素。所以,

>>> a = set()
>>> a.add(1)
>>> a
set([1])

可以,但是除非可哈希,否则它不能与可迭代对象一起使用。这就是a.add([1, 2])失败的原因。

>>> a.add([1, 2])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: unhashable type: 'list'

在这里,[1, 2]将其视为要添加到集合中的元素,并且如错误消息所言,列表不能被散列,但是集合中的所有元素都应该是可散列的。引用文档

返回其元素来自可迭代对象的newsetfrozensetobject。集合的元素必须是可哈希的

set.update

在的情况下set.update,您可以向其传递多个可迭代对象,它将迭代所有可迭代对象,并将集合中的各个元素包括在内。切记:它只能接受可迭代。这就是为什么当您尝试更新时出现错误的原因1

>>> a.update(1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'int' object is not iterable

但是,下面的方法将起作用,因为该列表[1]被迭代并且该列表的元素已添加到集合中。

>>> a.update([1])
>>> a
set([1])

set.update基本上等同于就地设置联合操作。考虑以下情况

>>> set([1, 2]) | set([3, 4]) | set([1, 3])
set([1, 2, 3, 4])
>>> set([1, 2]) | set(range(3, 5)) | set(i for i in range(1, 5) if i % 2 == 1)
set([1, 2, 3, 4])

在这里,我们将所有可迭代对象显式转换为集合,然后找到并集。有多个中间集和联合。在这种情况下,set.update可以充当好帮手功能。由于它接受任何迭代,因此您只需

>>> a.update([1, 2], range(3, 5), (i for i in range(1, 5) if i % 2 == 1))
>>> a
set([1, 2, 3, 4])

如果您要使用可迭代的可迭代对象集中的my_set进行更新my_set.update(*[s for s in iterable]),则传入一个生成器(如in一样) my_set.update(s for s in iterable)将使用可迭代的元素来更新该集合,并且如果这些元素不可散列
则将失败

19

add 单个元素的速度更快,因为它正是为此目的而添加单个元素的:

In [5]: timeit a.update([1])
10000000 loops, best of 3: 191 ns per loop

In [6]: timeit a.add(1) 
10000000 loops, best of 3: 69.9 ns per loop

update 期望有一个iterable或iterables,因此,如果您要添加单个hashable元素,则使用,add如果您要添加use则有一个hasherable元素的iterable或iterables update

s.add(x)将元素x添加到set s

s.update(t)s | = t返回带有从t添加的元素的set s


5
尽管这可能很明显,但应注意,update一次添加很多元素的速度要快得多:timeit a.update( range(10000) ) # => 1000 loops, best of 3: 431 µs per loop同时timeit for i in range(10000): a.add(i) # => 1000 loops, best of 3: 1.18 ms per loop
Matt Hancock


5

.add()用于单个element,而.update()用于引入其他集合。

从help():

add(...)
    Add an element to a set.

    This has no effect if the element is already present.


update(...)
    Update a set with the union of itself and others.


2

a.update(1)在您的代码中将无法正常工作。add接受一个元素并将其放置在集合中(如果尚不存在)但update采取可迭代的方法,并使该集合与该可迭代的联合。有点像appendextend列表。


1

我猜没有人提到Hackerrank的优秀资源。我想粘贴一下Hackerrank如何在python中提到update和add for set之间的区别。

集是唯一值的无序包。单个集合包含任何不可变数据类型的值。

创建集

myset = {1, 2} # Directly assigning values to a set

myset = set() # Initializing a set

myset = set(['a', 'b']) # Creating a set from a list

print(myset)  ===> {'a', 'b'}

修改设置-add()和update()

myset.add('c')

myset  ===>{'a', 'c', 'b'}

myset.add('a') # As 'a' already exists in the set, nothing happens

myset.add((5, 4))

print(myset) ===> {'a', 'c', 'b', (5, 4)} 


myset.update([1, 2, 3, 4]) # update() only works for iterable objects

print(myset) ===> {'a', 1, 'c', 'b', 4, 2, (5, 4), 3}

myset.update({1, 7, 8})

print(myset) ===>{'a', 1, 'c', 'b', 4, 7, 8, 2, (5, 4), 3}

myset.update({1, 6}, [5, 13])

print(myset) ===> {'a', 1, 'c', 'b', 4, 5, 6, 7, 8, 2, (5, 4), 13, 3}

希望能帮助到你。有关Hackerrank的更多详细信息,请点击此处。


0

add方法直接将元素添加到集合中,而update方法将第一个参数转换为集合,然后将列表添加为可哈希列​​表,因此我们无法将哈希列表添加到不可哈希集合中。


0

我们使用add()方法将单个值添加到集合中。

我们使用update()方法将序列值添加到集合中。

这里序列是任何iterables包括listtuplestringdict等。


1
关于已经存在的答案,实际上没有任何其他值。
colidyre '02
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.