如何操作嵌套列表

时间:2018-06-21 02:52:41

标签: python nested-lists

所以我目前有一个嵌套列表。

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()函数都没有用。感谢您的帮助。

2 个答案:

答案 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)

如果唯一元素的数量相对于集合的数量少,这是一种有效的方法。

步骤:

  1. 对于每个唯一元素,存储其中不会出现元素 的所有集合的索引。
  2. 对于网络中的每个集合s,使用第一步中的数据查找包含s的每个元素的所有其他集合。
  3. 遍历对,根据ID顺序丢弃重复项。

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())