如何在深层嵌套列表中获取公共元素:我的两个解决方案有效但需要一些时间

How to get common elements in a deep nested list: my two solutions work but take some time

我有一个嵌套列表结构,如下所示。 4 个嵌套结构中的每一个都代表了我的一些自由位置。 我想找出所有 4 个嵌套列表中都存在哪些元素。

ary=[   [[0, 4], [5, 11]],    [[0, 2], [0, 4], [5,10]],  [[0, 4], [0, 14], [5,11]],  [[0, 4], [0, 14], [5,11]]  ]

如上,在第一个嵌套列表 [[0, 4], [5, 11]] 中,[0,4] 存在于所有列表中,但 [5,11] 不存在。因此,我的答案应该是 [[0,4]] 甚至只是 [0,4].

我用两种方式做到了这一点。 解决方案1:

 ary1=ary
 newlist = [item for items in ary for item in items]
 x=[i for i in ary[0] if newlist.count(i)== len(ary1)]  

 #OUTPUT is x= [[0,4]]

解决方案2:

x=[]    
for u in ary[0]:
    n=[]        
    n=[1 for t in range(1,len(ary)) if u in ary[t]] 
    if len(ary)-1==len(n):  
       x.append(u)

#OUTPUT is x= [[0,4]]

使用线路分析器检查时,这两个似乎花费了相似的计算时间。这是我数百个代码中唯一需要大量计算的地方,我想减少它。 那么,你能推荐比这两个解决方案更好的其他 Python commands/code 吗?

我能想到的两种方法

  1. 根据您愿意接受的强度和目标列表的大小,可能需要一点时间和测试。 如果是这样,请考虑选项 2。但我的理论是将其转变为基于二进制的方法,而不是迭代外部数组的每个直接元素。 可能需要使用 itertools.tee() and/or 具有递归函数的多线程(取决于外部列表的长度)。 递归函数将在每次迭代中将列表分成两半,直到确定拆分的长度足够小以开始排除不常见的元素(如 [5-11])。 然后将公共元素传递回递归层次结构。 更紧密地设计它应该有助于评估 conditions/threshold 以避免失控情况,例如过多的线程数

  2. 似乎所有第三级列表(例如,[[0, 2]、[0, 4]、[5,10]])都已排序。如果不是,则对它们进行排序,消除(弹出)重复项,然后使用 + 运算符将它们全部合并在一起,然后求助。 之后,您将得到一个包含与 ary1 的长度一样多的 [0,4] 的结构。 这可能是您将 [0,4] 确定为答案的条件。 这可能需要再次测试

我不是建议这样做,我只是想出了另一种方法,所以你可以比较一下。也许这是一个幸运的机会,并且比您的主题方法需要更少的计算。

flatten_list = [tuple(item) for sublist in ary for item in sublist]
max(set(flatten_list), key = flatten_list.count)

这要求每个嵌套列表中始终存在一个元素,因为我没有明确检查它。

您可以尝试将第二层的每个嵌套数组转换为元组集合,其中每个最低层数组(即 [0,4])是该集合的一个元素。 需要转换为元组,因为列表不可散列。 将每个嵌套的列表列表作为一个集合后,只需找到它们的交集即可。

set.intersection(*[set(tuple(elem) for elem in sublist) for sublist in ary])