Python 组合具有重叠元素的列表

Python 组合具有重叠元素的列表,python,Python,我有一个列表集合,其中一些有重叠的元素: coll = [['aaaa', 'aaab', 'abaa'], ['bbbb', 'bbbb'], ['aaaa', 'bbbb'], ['dddd', 'dddd'], ['bbbb', 'bbbb', 'cccc','aaaa'], ['eeee','eeef','gggg','gggi'], ['gggg','hhhh','iiii']] 我只

我有一个列表集合,其中一些有重叠的元素:

coll = [['aaaa', 'aaab', 'abaa'],
        ['bbbb', 'bbbb'], 
        ['aaaa', 'bbbb'], 
        ['dddd', 'dddd'],
        ['bbbb', 'bbbb', 'cccc','aaaa'],
        ['eeee','eeef','gggg','gggi'],
        ['gggg','hhhh','iiii']]
我只想把重叠的列表集中在一起,这将产生

pooled = [['aaaa', 'aaab', 'abaa','bbbb','cccc'], 
          ['eeee','eeef','gggg','gggi','hhhh','iiii'],
          ['dddd', 'dddd']]
(如果不清楚,第一个和第二个列表都与第三个列表重叠,因此应该合并在一起,即使它们本身并不包含相同的元素。)

“重叠”指两个列表至少有一个共同元素。“合并”是指将两个列表合并为一个单一平面列表或一个单一平面集

可能有几个集合,例如x、y和z彼此重叠,v和w彼此重叠,但x+y+z不与v+w重叠。可能有一些列表与任何内容都不重叠

(一个类比是家庭。将所有的蒙太古家族连接在一起,将所有的卡普莱特家族连接在一起,但蒙太古家族从未与卡普莱特家族结过婚,因此这两个家族将保持不同。)

我不在乎重复的项目是否包含多次

用Python做这件事的简单且相当快速的方法是什么

<>编辑:这似乎不是重复的,因为这似乎不考虑只通过第三组重叠的组。我从这个问题中尝试的解决方案并没有得到我在这里寻找的答案。

这里有一种方法可以做到这一点(假设您希望重叠结果中有唯一的元素):

def over(coll):
打印('输入为:\n',coll)
#收集重叠的列表
重叠=[x表示coll中的x(如果有)(x中的x_元素[y表示coll中的k,如果k!=x表示y中的k]表示x中的x_元素)]
#扁平化并获得独特性
重叠=已排序(列表(集合([z代表x中的x,重叠代表x中的z]))
#得到其余的
非重叠=[x表示x在coll中,如果全部(y表示y在x中不重叠)]
#仅当需要合并的非重叠元素时,才使用下面的行
#非重叠=已排序([y代表x,非重叠代表y代表x])
打印('输出为“\n”,[重叠,非重叠])
coll=['aaaa','aaab','abaa'],
['bbbb','bbbb'],
['aaaa','bbbb'],
['dddd','dddddd'],
['bbbb','bbbb','cccc','aaaa']]
超过(coll)
coll=[['aaaa','aaaa'],['bbbb','bbbbbb']]
超过(coll)
输出:

$python3 over.py--正常--
输入为:
[['aaaa','aaab','abaa'],['bbbb','BBBBBB'],['aaaa','bbbb'],['dddd','dddd'],['BBBBBB','BBBBBB','CCC','aaaa']]
输出为“
[['aaaa','aaab','abaa','bbbb','cccc',[['dddd','dddd']]
输入为:
[['aaaa','aaaa'],['bbbb','bbbb']]
输出为“
[[]、[['aaaa'、['aaaa']、['bbbb'、['BBBBBB']]
这里有一种方法(假设您希望重叠结果上有唯一的元素):

def over(coll):
打印('输入为:\n',coll)
#收集重叠的列表
重叠=[x表示coll中的x(如果有)(x中的x_元素[y表示coll中的k,如果k!=x表示y中的k]表示x中的x_元素)]
#扁平化并获得独特性
重叠=已排序(列表(集合([z代表x中的x,重叠代表x中的z]))
#得到其余的
非重叠=[x表示x在coll中,如果全部(y表示y在x中不重叠)]
#仅当需要合并的非重叠元素时,才使用下面的行
#非重叠=已排序([y代表x,非重叠代表y代表x])
打印('输出为“\n”,[重叠,非重叠])
coll=['aaaa','aaab','abaa'],
['bbbb','bbbb'],
['aaaa','bbbb'],
['dddd','dddddd'],
['bbbb','bbbb','cccc','aaaa']]
超过(coll)
coll=[['aaaa','aaaa'],['bbbb','bbbbbb']]
超过(coll)
输出:

$python3 over.py--正常--
输入为:
[['aaaa','aaab','abaa'],['bbbb','BBBBBB'],['aaaa','bbbb'],['dddd','dddd'],['BBBBBB','BBBBBB','CCC','aaaa']]
输出为“
[['aaaa','aaab','abaa','bbbb','cccc',[['dddd','dddd']]
输入为:
[['aaaa','aaaa'],['bbbb','bbbb']]
输出为“
[[]、[['aaaa'、['aaaa']、['bbbb'、['BBBBBB']]

在评论中,我使用了networkx:

import networkx as nx

coll = [['aaaa', 'aaab', 'abaa'],
        ['bbbb', 'bbbb'], 
        ['aaaa', 'bbbb'], 
        ['dddd', 'dddd'],
        ['bbbb', 'bbbb', 'cccc','aaaa'],
        ['eeee','eeef','gggg','gggi'],
        ['gggg','hhhh','iiii']]

edges = []
for i in range(len(coll)):
    a = coll[i]
    for j in range(len(coll)):
        if i != j:
            b = coll[j]
            if set(a).intersection(set(b)):
                edges.append((i,j))

G = nx.Graph()
G.add_nodes_from(range(len(coll)))
G.add_edges_from(edges)

for c in nx.connected_components(G):
    combined_lists = [coll[i] for i in c]
    flat_list = [item for sublist in combined_lists for item in sublist]
    print(set(flat_list))
输出:

{'cccc', 'bbbb', 'aaab', 'aaaa', 'abaa'}
{'dddd'}
{'eeef', 'eeee', 'hhhh', 'gggg', 'gggi', 'iiii'}

毫无疑问,这是可以优化的,但现在似乎解决了我的问题。

根据评论中的建议,我使用了networkx:

import networkx as nx

coll = [['aaaa', 'aaab', 'abaa'],
        ['bbbb', 'bbbb'], 
        ['aaaa', 'bbbb'], 
        ['dddd', 'dddd'],
        ['bbbb', 'bbbb', 'cccc','aaaa'],
        ['eeee','eeef','gggg','gggi'],
        ['gggg','hhhh','iiii']]

edges = []
for i in range(len(coll)):
    a = coll[i]
    for j in range(len(coll)):
        if i != j:
            b = coll[j]
            if set(a).intersection(set(b)):
                edges.append((i,j))

G = nx.Graph()
G.add_nodes_from(range(len(coll)))
G.add_edges_from(edges)

for c in nx.connected_components(G):
    combined_lists = [coll[i] for i in c]
    flat_list = [item for sublist in combined_lists for item in sublist]
    print(set(flat_list))
输出:

{'cccc', 'bbbb', 'aaab', 'aaaa', 'abaa'}
{'dddd'}
{'eeef', 'eeee', 'hhhh', 'gggg', 'gggi', 'iiii'}

毫无疑问,这是可以优化的,但现在似乎解决了我的问题。

您可以使用连续合并方法对集合执行此操作:

coll = [['aaaa', 'aaab', 'abaa'],
        ['bbbb', 'bbbb'], 
        ['aaaa', 'bbbb'], 
        ['dddd', 'dddd'],
        ['bbbb', 'bbbb', 'cccc','aaaa'],
        ['eeee','eeef','gggg','gggi'],
        ['gggg','hhhh','iiii']]

pooled = [set(subList) for subList in coll]
merging = True
while merging:
    merging=False
    for i,group in enumerate(pooled):
        merged = next((g for g in pooled[i+1:] if g.intersection(group)),None)
        if not merged: continue
        group.update(merged)
        pooled.remove(merged)
        merging = True

print(pooled)
# [{'aaaa', 'abaa', 'aaab', 'cccc', 'bbbb'}, {'dddd'}, {'gggg', 'eeef', 'eeee', 'hhhh', 'gggi', 'iiii'}]

可以使用连续合并方法对集合执行此操作:

coll = [['aaaa', 'aaab', 'abaa'],
        ['bbbb', 'bbbb'], 
        ['aaaa', 'bbbb'], 
        ['dddd', 'dddd'],
        ['bbbb', 'bbbb', 'cccc','aaaa'],
        ['eeee','eeef','gggg','gggi'],
        ['gggg','hhhh','iiii']]

pooled = [set(subList) for subList in coll]
merging = True
while merging:
    merging=False
    for i,group in enumerate(pooled):
        merged = next((g for g in pooled[i+1:] if g.intersection(group)),None)
        if not merged: continue
        group.update(merged)
        pooled.remove(merged)
        merging = True

print(pooled)
# [{'aaaa', 'abaa', 'aaab', 'cccc', 'bbbb'}, {'dddd'}, {'gggg', 'eeef', 'eeee', 'hhhh', 'gggi', 'iiii'}]

你对重叠的定义是什么?你对合并的定义是什么?你能清理一下吗?看起来你需要连接的组件。每个列表指定组件中的顶点(例如,
aaaa
aaab
abaa
都在某个组件中,并且
aaaa
bbbbbb
是连接的,因此
bbbbbb
也在组件中)。这是一个很容易实现的传统图论问题——当然,网络上有很多资源可以解决这个问题,你甚至可以使用
networkx
让你的生活变得超级简单(它内置了用于连接组件的东西)。这个(不是选定的答案)可以解决你的问题。您只需要编写应答者不需要的
pairs
函数。你可以用这个。你对重叠的定义是什么?你对合并的定义是什么?你能清理一下吗?看起来你需要连接的组件。每个列表指定组件中的顶点(例如,
aaaa
aaab
abaa
都在某个组件中,并且
aaaa
bbbbbb
是连接的,因此
bbbbbb
也在组件中)。这是一个t