204

假设ST被分配集合。不使用 join operator |,如何找到两组的并集?例如,这会找到交集:

S = {1, 2, 3, 4}
T = {3, 4, 5, 6}
S_intersect_T = { i for i in S if i in T }

那么如何在不使用的情况下在一行中找到两组的并集|

4

9 回答 9

350

您可以对集合使用联合方法:set.union(other_set)

请注意,它返回一个新集合,即它不会修改自身。

于 2013-07-02T15:57:03.500 回答
56

您可以使用or_别名:

>>> from operator import or_
>>> from functools import reduce # python3 required
>>> reduce(or_, [{1, 2, 3, 4}, {3, 4, 5, 6}])
set([1, 2, 3, 4, 5, 6])
于 2013-09-26T11:51:35.710 回答
50

如果您可以修改原始集(在某些情况下您可能想要这样做),您可以使用set.update()

S.update(T)

返回值为None,但S将更新为原始S和的并集T

于 2018-03-06T19:52:36.867 回答
28

假设你也不能使用s.union(t),相当于s | t,你可以试试

>>> from itertools import chain
>>> set(chain(s,t))
set([1, 2, 3, 4, 5, 6])

或者,如果你想要理解,

>>> {i for j in (s,t) for i in j}
set([1, 2, 3, 4, 5, 6])
于 2013-07-02T15:12:46.180 回答
17

如果加入你的意思是联合,试试这个:

set(list(s) + list(t))

这有点像黑客,但我想不出更好的班轮来做到这一点。

于 2013-07-02T15:13:38.113 回答
16

您可以像这样将两个集合解压缩成一个:

>>> set_1 = {1, 2, 3, 4}
>>> set_2 = {3, 4, 5, 6}
>>> union = {*set_1, *set_2}
>>> union
{1, 2, 3, 4, 5, 6}

*打开包装。拆包是将可迭代对象(例如集合或列表)表示为它产生的每个项目。这意味着上面的示例简化为{1, 2, 3, 4, 3, 4, 5, 6}然后简化为,{1, 2, 3, 4, 5, 6}因为集合只能包含唯一项。

于 2020-04-10T18:46:11.297 回答
12

假设您有 2 个列表

 A = [1,2,3,4]
 B = [3,4,5,6]

所以你可以找到A联盟B如下

 union = set(A).union(set(B))

另外,如果您想找到交叉点和非交叉点,请执行以下操作

 intersection = set(A).intersection(set(B))
 non_intersection = union - intersection
于 2014-09-01T11:04:44.307 回答
5

你可以做union或简单的列表理解

[A.add(_) for _ in B]

A 将拥有 B 的所有元素

于 2015-05-13T13:02:50.253 回答
0

如果要加入n集合,最好的性能似乎是 from set().union(*list_of_sets),它将返回一个新集合。

因此,用法可能是:

s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = {4, 5, 6}

s1.union(s2, s3) # returns a new set
# Out: {1, 2, 3, 4, 5, 6}
s1.update(s2, s3) # updates inplace

添加到上面Alexander Klimenko的答案中,我做了一些简单的测试,如下所示。我相信主要的收获是,似乎集合越随机,性能差异就越大

from random import randint

n = 100

generate_equal = lambda: set(range(10_000))
generate_random = lambda: {randint(0, 100_000) for _ in range(10_000)}

for l in [
    [generate_equal() for _ in range(n)],
    [generate_random() for _ in range(n)]
]:
    %timeit set().union(*l)
    %timeit reduce(or_, l)
Out:
  # equal sets: 69.5 / 23.6 =~ 3
  23.6 ms ± 658 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
  69.5 ms ± 2.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
  # random sets: 438 / 78.7 =~ 5.6
  78.7 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
  438 ms ± 20.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

因此,如果要就地更新,最好的性能来自set.update方法,因为性能方面,s1.update(s2, s3) = set().union(s2, s3).

于 2022-03-03T19:34:05.783 回答