首页 > 解决方案 > 通过其中一个中的重复元素过滤两个不规则列表

问题描述

一段时间以来,我一直在摆弄看似简单的问题,但找不到简单的答案。考虑这两个列表列表:

a1 = [
    [[0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34],
     [0.3, 2.1, 3.3, 4.66, 8.9, 11.34],
     [0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34],
     [0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34]],
    [[0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34],
     [0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34],
     [0.3, 1.75, 2.1, 4.66, 8.9, 11.34],
     [0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34]]
]

a2 = [
    [[2, 3, 5, 8, 13, 21, 35],
     [2, 5, 8, 13, 21, 35],
     [2, 3, 5, 8, 13, 21, 35],
     [2, 3, 5, 8, 13, 21, 35]],
    [[2, 3, 5, 8, 13, 21, 35],
     [2, 3, 5, 8, 13, 21, 35],
     [2, 3, 5, 13, 21, 35],
     [2, 3, 5, 8, 13, 21, 35]]
]

它们的形状是(N, M, P*),其中P*表示P所有子列表中的元素数量不同(但对于与 中的子列表a2具有相同索引的子列表,它是相同的a1)。有时这两个列表是完整的,并且所有子列表将包含相同的元素,即(在此示例中):0.3, 1.75, 2.1, 3.3, 4.66, 8.9, 11.34对于 中的所有子列表a12, 3, 5, 8, 13, 21, 35对于 中的所有子列表a1。在这种情况下,形状是(N, M, P)

我需要一种方法来根据可以在所有 子列表中找到的元素同时过滤两个列表。在上面的示例中,某些子列表中缺少元素和,因此结果将是:a11.753.3a1

a1_f = [0.3, 2.1, 4.66, 8.9, 11.34]
a2_f = [2, 5, 13, 21, 35]

从哪里38从哪里删除,a2因为它们链接到非重复元素1.75并且3.3a1.

我的实际列表会更大且形状任意,因此我采用一般方法。两个列表中的元素总是从最小到最大排序,但我不确定它有什么区别。

任何帮助都感激不尽。

标签: pythonlistfilter

解决方案


我相信以下内容可以满足您的要求,而无需构造不必要的数组副本:

from functools import reduce
rows = ((set(r1), set(r2)) for c1, c2 in zip(a1, a2) for r1, r2 in zip(c1, c2))
a1_f, a2_f = reduce(lambda a_f, row: (a_f[0] & row[0], a_f[1] & row[1]), rows)

它将所有列表收集到一个生成器中,一次两个,将它们转换为集合。然后它计算交点以找到最小的集合。如果您需要将结果作为列表,您可以使用list(a1_f)etc将它们转换回来。

也就是说,通过同时过滤两个列表来获得什么并不明显。分别执行每一项将使代码更简单,并且不会减慢速度。


推荐阅读