可迭代对象差异和公共元素

Iterables difference and common elements

提问人:alvas 提问时间:11/10/2023 最后编辑:alvas 更新时间:11/10/2023 访问量:55

问:

给定 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 = []

解释:

  • 当涉及到元素时,x 有 2 个计数,y 有 1 个计数,所以是共同的,另一个是x_only的。2[2][2]
  • 类似地,x 有 3 个计数,y 有 1 个计数。所以会很常见,另一个会x_only。5[5][5,5]
  • 和 中元素的顺序并不重要。commonx_onlyy_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 列表 计数器 可迭代

评论

0赞 JRiggles 11/10/2023
5 和 2 在 x 中不是“唯一”
2赞 Mathias R. Jessen 11/10/2023
是什么阻止了您创建每个计数器一次并将其分配给变量?而不是实例化 6
0赞 ShadowRanger 11/10/2023
对于每个示例,您的输入都不同,这会造成一些混淆。
1赞 ShadowRanger 11/10/2023
@Codist:它们是差异计数,而不是唯一元素。 具有多的 s(在这两个示例中,尽管示例不同意有多少),因此多余的存活。x5y
2赞 ShadowRanger 11/10/2023
@MathiasR.Jessen:从技术上讲,是九个,因为每个非就地二进制运算符都会产生另一个 .Counter

答:

3赞 ShadowRanger 11/10/2023 #1

你的解决方案很好,只需通过只构造每个唯一对象一次来消除冗余,首先进行交集,这样就可以减少组成唯一结果的工作量,这将使你能够完成大部分工作(所以只构造了三个对象,而不是九个):CounterCounter

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())

它有更多的线条,但完成的工作更少,任何给定的线都远没有那么复杂。