Iterables的区别和共同元素

问题描述 投票:0回答:2

给定 2 个迭代/列表,目标是从两个列表中提取共同和不同的元素。

例如,给定:

x, y = [1,1,5,2,2,3,4,5,5], [2,3,4,5]

目标是实现:

common = [2,3,4,5]
x_only = [1,1,5,2,5]
y_only = []

说明:

  • 当涉及到元素
    2
    时,x有2个计数,y有1个计数,因此
    [2]
    将是公共的,而另一个
    [2]
    将在x_only中。
  • 类似地,对于
    5
    ,x 有 3 个计数,y 有 1 个计数。所以
    [5]
    将很常见,而另一个
    [5,5]
    将在 x_only 中。
  • common
    x_only
    y_only
    的顺序并不重要。

我已经尝试过:

from collections import Counter

x, y = [1,1,5,2,3,4,5], [2,3,4,5]

x_only = list((Counter(x) - Counter(y)).elements())
y_only = list((Counter(y) - Counter(x)).elements())
common = list((Counter(x) & Counter(y)).elements())

上述尝试达到了目的,但重复多组/计数器减法和交集似乎有点多余。它适用于小型可迭代对象,但不适用于大型列表,例如1-100 亿项。

python list counter iterable
2个回答
0
投票

这是一个利用一些列表理解的解决方案

x, y = [1,1,5,2,3,4,5], [2,3,4,5]

x_only = [n for n in x if n not in y]
y_only = [n for n in y if n not in x]
common = [n for n in x if n in x and n in y]
print(x_only, y_only, common)
# => [1, 1] [] [5, 2, 3, 4, 5]

请注意,

x_only
包括
2
5
,因为这些数字确实出现在列表中
y
...如果您想要那个结果,您将不会得到它。


0
投票

您的解决方案很好,只需通过仅构造每个唯一的

Counter
一次,通过使交集first来消除冗余,这样就可以减少组成唯一结果的工作,这将使您可以就地完成大部分工作(所以只构造了三个独特的
Counter
,而不是五个):

from collections import Counter

x, y = [1,1,5,2,3,4,5], [2,3,4,5]

cx = Counter(x)
cy = Counter(y)
both = cx & cy
cx -= both
cy -= both
x_only = list(cx.elements())
y_only = list(cy.elements())
common = list(both.elements())

线路更多,但完成的工作更少,并且任何给定的线路都不那么复杂。

© www.soinside.com 2019 - 2024. All rights reserved.