如何解决从列表列表中,如何查找具有n个共同元素的列表 性能:
我有一个列表列表
foo = [[1,2,4,17],[1,12],5,17]]
我有兴趣找到共享n个元素的所有可能列表组。
预期结果:
列表共享3个元素
- 包含[1,4]的组:
[[1,12]]
- 包含[1,17]的组:
[[1,17]]
列表共享2个元素
- 包含[1,2]的组:
[[1,17]]
- 包含[1,12]]
- 包含[2,17]]
- 包含[2,17]]
到目前为止我尝试过的事情
- 列表的交集:它无法解决我的问题,因为我无法控制希望共享列表的元素数量。
我想尝试的方法,但看起来确实很复杂,而且必须是更方便的方法
- 对于每个列表,请定义列表的所有组合减去一个元素(即子集)。
- 遍历其余列表,并将包含子集的列表存储在字典中
我在这里发布了一个最小的示例,但实际上我有一个包含数百个列表的列表,每个列表包含6个元素,因此我也担心组合爆炸。
如果有人可以提供一些指导或技巧,那就太好了。
非常感谢,
最佳
解决方法
这应该可以帮助您:
from itertools import combinations
def isSubset(comb,lst):
it = iter(lst)
return all(c in it for c in comb)
foo = [[1,2,4,17],[1,12],5,17]]
n = 3
print('-'*100)
print(f"n = {n}")
existing = []
for index in range(len(foo)):
combs = combinations(foo[index],n)
for comb in combs:
occurrences = 0
curr_lst = []
for lst in foo:
if isSubset(comb,lst):
if comb not in existing:
occurrences += 1
curr_lst.append(lst)
if occurrences >= 2:
if occurrences == 2:
print('-' * 100)
print(f"Groups containing {comb}")
[print(elem) for elem in curr_lst]
else:
print(lst)
existing.append(comb)
输出:
----------------------------------------------------------------------------------------------------
n = 3
----------------------------------------------------------------------------------------------------
Groups containing (1,4)
[1,17]
[1,12]
----------------------------------------------------------------------------------------------------
Groups containing (1,17)
[1,17]
n=2
的输出:
----------------------------------------------------------------------------------------------------
n = 2
----------------------------------------------------------------------------------------------------
Groups containing (1,2)
[1,12]
[1,17]
----------------------------------------------------------------------------------------------------
Groups containing (1,17]
----------------------------------------------------------------------------------------------------
Groups containing (2,12]
----------------------------------------------------------------------------------------------------
Groups containing (2,17]
,
我不认为有一种简单的方法可以为每个内部列表生成具有n个元素的所有组合。但是每个组合只需检查一次:
from itertools import combinations
import random
n = 3
foo = [[random.randint(0,100) for _ in range(6)] for _ in range(500)]
#foo = [[1,17]]
checked = set() # already checked combinations
result = []
for lst in foo:
cbs = combinations(lst,n)
for comb in cbs:
if not comb in checked:
groups = [l for l in foo if all(i in l for i in comb)]
if len(groups) > 1:
result.append((comb,groups))
checked.add(comb)
print(result)
输出:
[((1,4),[[1,12]]),((1,17),17]])]
性能:
对于具有500个子列表的随机生成的列表,子列表内的值介于0-100或0-1000以及n=2
或n=3
,代码需要花费几秒钟来完成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。