我需要将具有相同元素的子列表组合在一起 例如:
list1 =[[1, 0], [2, 1], [30, 32]]
会将[1, 0]
和[2, 1]
联系在一起,因为它们都包含1
,而这两者会合并为[0, 1, 2]
所以在链接之后,新列表应该是:
new_list1 = [[1, 0, 2], [30, 32]]
IE:在子列表中不应该是相同的数字,顺序并不重要。
更长的例子:
list2 = [[2, 3], [4, 3], [6, 5], [7, 6], [7, 8], [13, 14], [30, 32]]
链接后将是
new_list2 = [[2, 3, 4], [6, 5, 7, 8], [13, 14], [30, 32]]
那么如何以一般方式完成呢?
答案 0 :(得分:2)
要以一般方式对子列表进行分组,您可以:
def linking_sublists(lists):
index = {}
sets = []
for l in lists:
found = None
for i in l:
if i in index:
# this list has an element we have already seen
if found:
# combine two sets
to_remove = index[i]
if found != to_remove:
for j in index[i]:
found.add(j)
index[j] = found
to_remove.clear()
else:
found = index[i]
if found is not None:
s = found
for i in l:
s.add(i)
else:
s = set(l)
sets.append(s)
for i in l:
index[i] = s
return [list(sorted(s)) for s in sets if s]
此函数使用集合和索引dict
将具有匹配元素的任何列表分组到集合中,并跟踪哪些元素已在set
中。
list_2 = [[2, 3], [4, 3], [6, 5], [7, 6], [7, 8], [13, 14], [30, 32]]
print(linking_sublists(list_2))
list_3 = [[2, 3], [4, 3], [6, 5], [7, 6], [7, 8], [30, 32], [4, 5], [3, 4]]
print(linking_sublists(list_3))
[[2, 3, 4], [5, 6, 7, 8], [13, 14], [30, 32]]
[[2, 3, 4, 5, 6, 7, 8], [30, 32]]
答案 1 :(得分:1)
查看此问题的一种方法是将每个子列表视为图中的节点。如果两个节点具有共同项,则它们共享边缘。
然后可以使用图形的岛("connected components" or just "components")来构建新列表。 list2
的图表如下所示:
[2,3]<--->[4,3]
[6,5]<--->[7,6]<--->[7,8]
[13,14] [30,32]
代码草图(未经测试):
list2=[[2,3],[4,3],[6,5],[7,6],[7,8],[13,14],[30,32]]
# Convert to tuples for easier handling
l2 = [tuple(item) for item in list2]
# Build a graph
graph = {item: set() for item in l2}
for sublist in l2:
for sublist2 in l2:
if sublist == sublist2:
continue
for item in sublist:
if item in sublist2:
graph[sublist].add(sublist2)
# Find all nodes that start_node is connected to
def island(graph, start_node):
visited = set()
visited.add(start_node)
frontier = set(graph[start_node])
while frontier:
node = frontier.pop()
visited.add(node)
frontier.update(n for n in graph[node] if n not in visited)
return visited
# Find all islands
islands = []
for sublist in l2:
i = island(graph, sublist)
if i not in islands:
islands.append(i)
# Build the new lists by getting all unique numbers from each island
[list(set(item for sublist in island for item in sublist)) for island in islands]
# Output:
# [[2, 3, 4], [8, 5, 6, 7], [13, 14], [32, 30]]
以上内容可以改进,无论是构建图表的方式还是找到组件的方式都可以提高效率。
这种思维可以用来解决许多不同的问题。也就是说,我更喜欢Stephen Rauch的解决方案,因为它简单。