所以我目前有一个嵌套列表。
org_network=[[1, 2, 3], [1, 4, 5], [1, 3, 6], [7, 9, 10]]
我需要弄清楚如何操纵它来创建嵌套列表的可能组合的列表。这些组合不能具有共享号码的列表。这是结果的示例:
network_1=[[1,2,3],[7,9,10]]
network_2=[[1,4,5],[7,9,10]]
network_3=[[1,3,6],[7,9,10]]
注意: 1.该代码将链接到一个不断更新的csv文件,因此org_network列表中将包含不同数量的元素(这也意味着将有许多生成的网络。
我已经研究了大约四个小时,但还没有弄清楚。任何帮助将不胜感激。我主要是试图使用循环和any()函数都没有用。感谢您的帮助。
答案 0 :(得分:0)
您可以将itertools.combinations()
与设置的交集一起使用:
>>> from itertools import combinations
>>> org_network=[[1, 2, 3], [1, 4, 5], [1, 3, 6], [7, 9, 10]]
>>> [[x, y] for x, y in combinations(org_network, r=2) if not set(x).intersection(y)]
[[[1, 2, 3], [7, 9, 10]], [[1, 4, 5], [7, 9, 10]], [[1, 3, 6], [7, 9, 10]]]
答案 1 :(得分:0)
如果唯一元素的数量相对于集合的数量少,这是一种有效的方法。
步骤:
s
,使用第一步中的数据查找包含s
的每个元素的所有其他集合。from functools import reduce
org_network = [[1, 2, 3], [1, 4, 5], [1, 3, 6], [7, 9, 10]]
# convert to sets
sets = [set(lst) for lst in org_network]
# all unique numbers
uniqs = set().union(*sets)
# map each unique number to sets that do not contain it:
other = {x: {i for i, s in enumerate(sets) if x not in s} for x in uniqs}
# iterate over sets:
for i, s in enumerate(sets):
# find all sets not overlapping with i
no_overlap = reduce(lambda l, r: l.intersection(r), (other[x] for x in s))
# iterate over non-overlapping sets
for j in no_overlap:
# discard duplicates
if j <= i:
continue
print([org_network[i], org_network[j]])
# result
# [[1, 2, 3], [7, 9, 10]]
# [[1, 4, 5], [7, 9, 10]]
# [[1, 3, 6], [7, 9, 10]]
编辑:如果需要大于两个的大小组合,则可以修改上述方法。这是一个使用深度优先搜索来遍历所有成对不相交组合的扩展。
def not_overlapping(set_ids):
candidates = reduce(
lambda l, r: l.intersection(r), (other[x] for sid in set_ids for x in sets[sid])
)
mid = max(set_ids)
return {c for c in candidates if c > mid}
# this will produce "combinations" consisting of a single element
def iter_combinations():
combs = [[i] for i in range(len(sets))]
while combs:
comb = combs.pop()
extension = not_overlapping(comb)
combs.extend(comb + [e] for e in extension)
yield [org_network[i] for i in comb]
def iter_combinations_long():
for comb in iter_combinations():
if len(comb) > 1:
yield comb
all_combs = list(iter_combinations_long())