集合中的 union() 和 _update() 的区别

【问题描述】:Difference between union() and update() in sets, and others?

Python 集合有这些方法:

s.union(t)  s | t   new set with elements from both s and t

s.update(t) s |= t  return set s with elements added from t

同样,还有这些:

s.intersection_update(t)    s &= t  return set s keeping only elements also found in t

s.intersection(t)   s & t   new set with elements common to s and t

等等,对于所有标准的关系代数运算。

所以...问题是,这里到底有什么区别?我看到它说 update() 版本返回 s 而不是新集合,但是如果我写 x = s.update(t),这是否意味着 id(x) == id(s)?它们现在是否引用同一个对象

【解决方案1】:

它们非常不同。一个集合原地更改集合,而另一个保留原始集合,并返回一个副本

>>> s = {1, 2, 3}
>>> news = s | {4}
>>> s
set([1, 2, 3])
>>> news
set([1, 2, 3, 4])

注意s 是如何保持不变的。

>>> s.update({4})
>>> s
set([1, 2, 3, 4])

现在我已经更改了s 本身。另请注意,.update() 似乎没有返回任何内容;它没有向调用者返回s,Python 解释器也没有回显一个值。

就地更改对象的方法永远不会在 Python 中返回原始对象。它们的返回值始终是 None(永远不会回显)。

【讨论】:

  • 哈,14 个月后,它的工作原理是如此明显,以至于我不得不问。不过谢谢....这是一个过程。

  • 请注意s1.update(s2) 等价于s1|=s2。我想知道两者之间是否有任何性能差异。

  • @YiboYang:我跑了timeit试用;没有太大区别; s1|=s2 稍微慢一些(大约 1-2%)。考虑到增强的|= 分配确实会重新分配回s1,即使该对象首先就地更新(如果目标名称首先是类属性或不可变对象的元素,这可能会产生后果) .

【解决方案2】:

看起来文档并没有以最清晰的方式说明它,但 set.update 根本没有返回任何东西(相当于返回 None),也没有set.intersection_update。像list.append 或list.extend 或dict.update 一样,它们会修改容器。

In [1]: set('abba')
Out[1]: set(['a', 'b'])

In [2]: set('abba').update(set('c'))

In [3]: 

 

编辑:实际上,the docs 不要说你在问题中显示的内容。他们说:

更新集合,添加所有其他元素。

更新集合,只保留其中找到的元素和所有其他元素。

【讨论】:

  • OP 引用的内容不是来自official docs for sets

  • @Aerovistae 2.7.3 并没有过时,但您可能阅读的不是官方文档。

【解决方案3】:

_update 方法就地修改集合并返回 None。没有update 的方法返回一个新对象。你几乎肯定不想做x = s.update(t),因为这会将x 设置为无。

>>> x = set([1, 2])
>>> x.intersection(set([2, 3]))
set([2])
>>> x
set([1, 2])
>>> x.intersection_update(set([2, 3]))
>>> x
set([2])
>>> x = x.intersection_update(set([2, 3]))
>>> print x
None

_update 方法添加的功能是能够修改现有集合。如果您在多个对象之间共享一个集合,您可能需要修改现有集合,以便共享它的其他对象看到更改。如果你只是创建一个新集合,其他对象不会知道它。

转载自https://www.likecs.com/ask-296957.html#sc=312.3333435058594

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值