【问题标题】:add vs update in set operations in python在python的集合操作中添加vs更新
【发布时间】:2020-02-23 00:55:30
【问题描述】:

如果我只想将单个值添加到集合中,python 中的添加和更新操作有什么区别。

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

谁能解释一下为什么会这样。

【问题讨论】:

  • 您使用的是什么版本的 Python?对于a.update(1),我期望TypeError: 'int' object is not iterable,并且在我尝试过的两个版本中都得到了它。
  • @thefootheye,你的编辑改变了很多问题
  • @PadraicCunningham 我们都知道这行不通。我们可以同意这只是一个复制/粘贴错误吗?如果没有,请随时恢复我的修订:)
  • @thefoureye 是的,这是我的复制粘贴错误

标签: python set


【解决方案1】:

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] 被视为添加到集合中的元素,并且如错误消息所述,a list cannot be hashed 但集合中的所有元素都应该是可散列的。引用documentation

返回一个新的setfrozenset 对象,其元素取自可迭代对象。集合的元素必须是hashable

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]),像my_set.update(s for s in iterable)一样传入一个生成器将使用可迭代对象的元素更新集合和如果这些元素不可哈希
【解决方案2】:

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 需要一个或多个可迭代元素,因此如果您要添加单个可散列元素,则使用 add 如果您要添加可迭代元素或可迭代元素,则使用 update

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

s.update(t) s |= t 返回从 t​​ 添加元素的集合 s

【讨论】:

  • 虽然这可能很明显,但应该注意update 一次添加大量元素要快得多:timeit a.update( range(10000) ) # =&gt; 1000 loops, best of 3: 431 µs per loop,同时timeit for i in range(10000): a.add(i) # =&gt; 1000 loops, best of 3: 1.18 ms per loop
【解决方案3】:

add 添加一个元素,update“添加”另一个可迭代的setlisttuple,例如:

In [2]: my_set = {1,2,3}

In [3]: my_set.add(5)

In [4]: my_set
Out[4]: set([1, 2, 3, 5])

In [5]: my_set.update({6,7})

In [6]: my_set
Out[6]: set([1, 2, 3, 5, 6, 7])

【讨论】:

【解决方案4】:

.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.

【讨论】:

    【解决方案5】:

    add 只接受可散列类型。列表不可散列。

    【讨论】:

      【解决方案6】:

      a.update(1) 在您的代码中不起作用。 add 接受一个元素并将其放入集合中(如果它尚不存在),但 update 接受一个可迭代对象并将该集合与该可迭代对象进行联合。有点像 appendextend 的列表。

      【讨论】:

        【解决方案7】:

        我想没有人提到 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'}
        

        修改 SET - 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 的更多详细信息,here is the link.

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

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

            这里的序列是任何可迭代对象,包括list,tuple,string,dict 等。

            【讨论】:

            • 对于已经存在的答案实际上没有任何附加值。
            猜你喜欢
            • 2021-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-22
            • 1970-01-01
            相关资源
            最近更新 更多