【问题标题】:Difference between union() and update() in sets, and others?集合中的 union() 和 union_update() 和其他之间的区别?
【发布时间】:2012-12-04 01:06:12
【问题描述】:

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)?它们现在是否引用同一个对象?

我的意思是,我真的不明白为什么要实现这两组方法。它似乎没有添加任何重要的功能。

【问题讨论】:

  • 呸,我无意中阅读了过时的文档。
  • 那在哪里? 2.7.3 sets documentation 不使用您引用的语言。
  • docs.python.org/2/library/sets.html -- 不幸的是,当你用谷歌搜索“python 集”时会出现这种情况。
  • 啊,你找到了旧的sets module;后来添加了 set 内置 type 来替换该模块。在顶部它声明 自 2.6 版起已弃用:内置的 set/frozenset 类型替换了此模块。
  • 该模块的文档实际上也不正确。我检查了source code*_update() 方法也返回 None。

标签: python set set-operations


【解决方案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.appendlist.extenddict.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 方法添加的功能是能够修改现有集合。如果您在多个对象之间共享一个集合,您可能需要修改现有集合,以便共享它的其他对象看到更改。如果你只是创建一个新集合,其他对象不会知道它。

【讨论】:

    猜你喜欢
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 2015-03-29
    • 2016-07-23
    • 2021-10-04
    • 2020-10-03
    相关资源
    最近更新 更多