Python 找到子列表之间的交集
最近我遇到一个关于查找子列表之间的交集的问题。这告诉子列表,其中有任何(1个或多个)交集一起成为一个。例如,以下列表:Python 找到子列表之间的交集,python,list,numpy,data-structures,intersection,Python,List,Numpy,Data Structures,Intersection,最近我遇到一个关于查找子列表之间的交集的问题。这告诉子列表,其中有任何(1个或多个)交集一起成为一个。例如,以下列表: l=[[1,2,3],[0,13,6],[9,10],[3,4,5],[10,11],[6,7,50]] 必须转换为: [[1, 2, 3, 4, 5],[0, 50, 6, 7, 13],[9, 10, 11]] 因此,我编写了以下函数来实现这一点,该函数运行良好,性能良好,我使用set检查成员身份的快速复杂性,在内部循环中,我使用切片将主列表的第一个索引与每个循环中的
l=[[1,2,3],[0,13,6],[9,10],[3,4,5],[10,11],[6,7,50]]
必须转换为:
[[1, 2, 3, 4, 5],[0, 50, 6, 7, 13],[9, 10, 11]]
因此,我编写了以下函数来实现这一点,该函数运行良好,性能良好,我使用set
检查成员身份的快速复杂性,在内部循环中,我使用切片将主列表的第一个索引与每个循环中的其他元素进行比较,并注意到每个循环后列表将减少,因为它是循环内部的递归:
s=[set(i) for i in g if i]
def find_intersection(m_list):
for i,v in enumerate(m_list) :
for j,k in enumerate(m_list[i+1:],i+1):
if v & k:
s[i]=v.union(m_list.pop(j))
return find_intersection(m_list)
return m_list
s=[set(i) for i in l if i]
print find_intersection(s)
[set([1, 2, 3, 4, 5]), set([0, 50, 6, 7, 13]), set([9, 10, 11])]
但我认为可以用另一种解决方案来实现,可能性能更好,我考虑过使用
collections.deque
,或者使用numpy
,或者只是修改我的函数并使其更好。如果您有任何建议,我将不胜感激 这里有一个更有效的算法:
O(n*log n)
时间;如果我们使用哈希表,则此部分为O(n)
,其中n
是所有子列表中的元素总数O(n)
edges(这一部分非常重要:不需要显式地创建所有边,我们只需在每个子列表中为所有唯一元素的下一个元素添加一条边即可)。下面是一些伪代码:
g = empty graph
for elem in unique_elements:
sublist_indices = list of indices of all sublists that contain this element
for i = 1 ... size(sublist_indices - 1):
g.add_edge(sublist_indices[i], sublist_indices[i + 1])
总时间复杂度为
O(n)
。它是最优的,因为读取输入已经需要O(n)
操作。这还不错,但我认为您没有很好地理解我的代码,我使用集合来检查成员身份,因为它的O(1)
,而我使用2来检查它的非O(n^2)
可能是因为内部列表的长度以及主列表在任何循环后都会减少。@Kasra您的代码至少是O(n^2)
(可能更多)。例如,如果所有子列表只包含一个元素,并且只有最后两个元素相交,那么将进行n*(n-1)/2次迭代。有一点。@Kasra试试这个测试用例:[[1],[2],…,[n-2],[n],[n]]。毫无疑问,您的解决方案会对它执行O(n^2)
操作。加上1。我必须说,我知道这一点,但我没有理解。所以这是最坏的情况!由于您的解决方案是一个很好的解决方案算法,我需要等待pythonic的建议。如果您能解释代码适合解决OP问题的内容和原因,我会很有帮助。
l=[[1,2,3],[0,13,6],[9,10],[3,4,5],[10,11],[6,7,50]]
temp = []
result = []
for i in range(len(l)):
for j in range(i + 1, len(l)):
if set(l[i]).intersection(l[j]):
temp.append(l[i] + l[j])
result.append(list(set(temp[i])))
print result