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

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

提问人:knowledge_seeker 提问时间:4/14/2022 更新时间:4/14/2022 访问量:596

问:

我有一个嵌套列表结构,如下所示。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]],甚至只是 [0,4]。[[0, 4], [5, 11]][0,4][5,11]

我通过两种方式做到这一点。解决方案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 命令/代码?

Python 列表 索引列表 嵌套列表

评论


答:

0赞 mhega 4/14/2022 #1

我能想到的两种方法

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

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

评论

0赞 knowledge_seeker 4/15/2022
非常好的见解。
1赞 Rabinzel 4/14/2022 #2

我不是建议这样做,我只是想出了另一种方法,以便您可以进行比较。也许这是一个幸运的镜头,比你的主题方式需要更少的计算。

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

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

评论

0赞 knowledge_seeker 4/15/2022
这有效,但即使我从第二个嵌套列表中删除,它仍然显示我的答案。但也许这就是你最后提到的。[0,4](0,4)
0赞 Rabinzel 4/15/2022
是的,我没有检查它是否在所有部分,只是搜索最大的计数
1赞 artemshramko 4/14/2022 #3

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

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

评论

0赞 knowledge_seeker 4/15/2022
在我的场景中,这工作得更快。我用这个代替了我的两个解决方案!