Python链接子列表,子列表在list2中没有元素,并且在list3中有一个元素

时间:2017-05-29 12:46:09

标签: python list

我需要将具有相同元素的子列表组合在一起,并且子列表中的所有元素在list2中都没有元素,并且在list3中有一个元素 例如:

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[13,15]]
list2 = [7,8]
list3 = [1,6,11,13]

我会将[4,5][1,4]联系在一起,因为它们都包含1个相同的数字,而这两个数字会合并为[1,4,5],并且1中包含list3并且7

中不包含list2

所以在链接之后,新列表应该是:

new_list1 = [[1,4,5],[6],[11],[13,15]]

IE:子列表中不应该有相同的数字,顺序并不重要。

更长的例子:

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]]
list2 = [7,8,20]
list3 = [1,2,3,16,15]
链接后

将是

new_list = [[1,4,5],[2,3],[11,14,16],[13,15]]

如何以一般方式完成?

修改 最终算法应包括以下三个基本步骤:

  1. 删除list1
  2. 中包含的list2所有子列表的所有元素
  3. 加入所有具有共同元素的list1子列表
  4. 删除所有不包含list1
  5. 元素的list3子列表

3 个答案:

答案 0 :(得分:2)

如果托马斯·库恩能够正确地读懂你的想法,那就是我的看法:

def subgroup_join(data, exclude, include):
    exclude = set(exclude)  # turn into set for faster lookup/compare
    include = set(include)  # turn into set for faster lookup/compare
    data = [set(element) - exclude for element in data]  # remove excluded elements
    results = [set()]  # init with an empty set
    for element in data:  # loop through our remaining elements
        groups = []  # store elements / current results filtered by exclude list
        ignore_element = False  # flag if we should add the element as a standalone
        for result in results:  # go through each subgroup in the results
            if element & result:  # if the current element has common items with the result
                result |= element  # ... concatenate both into a subgroup
                ignore_element = True
            groups.append(result)  # add the current result subgroup
        if not ignore_element:  # add only if the element wasn't concatenated
            groups.append(element)  # add the current element
        results = groups  # our element store becomes our new results set
    return sorted([sorted(res) for res in results if result & include])  # sort & return

至于测试:

list1 = [[1, 4], [4, 5], [5, 7], [6, 7], [7, 8], [9, 7], [10, 9], [8, 10], [8, 11], [8, 13], [13, 15]]
list2 = [7, 8]
list3 = [1, 6, 11, 13]

print(subgroup_join(list1, list2, list3))
# prints: [[1, 4, 5], [6], [11], [13, 15]]

list1 = [[1, 4], [4, 5], [5, 7], [6, 7], [9, 7], [10, 9], [8, 10], [8, 11], [8, 13], [6, 8], [20, 2], [20, 3], [11, 14], [14, 16], [13, 15]]
list2 = [7, 8, 20]
list3 = [1, 2, 3, 16, 15]

print(subgroup_join(list1, list2, list3))
# prints: [[1, 4, 5], [2], [3], [11, 14, 16], [13, 15]]

这可能是所提出的最快的方法,但同样 - 它与您的示例不完全匹配 - 请检查上一个结果集以及[2][3]结果。

<强>更新

在性能方面,使用第二个列表组:

zwer_join - 100,000 loops: 2.849 s; per loop: 28.399 µs
kuhn_join - 100,000 loops: 3.071 s; per loop: 30.706 µs
nuag_join -   1,000 loops: 15.82 s; per loop: 15.819 ms (had to reduce the number of loops)

答案 1 :(得分:1)

此代码应该完成这项工作:

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]]
list2 = [7,8,20]
list3 = [1,2,3,16,15]

list1a = [set(l) for l in list1]
#removing elements from list1 that contain numbers of list2:
for x in list2:
    for l in list(list1a):
        if x in l:
            l.remove(x)

#joining sub-lists in list1:
list1b = [set(l) for l in list1a]
list1c = []
while list1b:
    s1 = list1b.pop(0)
    for s2 in list(list1b):
        if s1 & s2:
            s1 |= s2
            list1b.remove(s2)
    list1c.append(s1)

#generating final list with only sub-lists that contain elements of list2
list1_new = sorted([sorted(list(s)) for s in list1c if s & set(list3)])

对于第一个例子,这给出了:

[[1, 4, 5], [6], [11], [13, 15]]

和第二个例子

[[1, 4, 5], [2], [3], [11, 14, 16], [13, 15]]

希望这有帮助。

答案 2 :(得分:0)

首先,您首先要编写join函数。我添加了第二个列表来删除不需要的元素。

然后,您遍历加入列表,查看列表中是否有任何元素。如果是,则查找它们所在的位置,然后添加元素(我使用set以避免重复)。

最后给出了输出。

def join(list1, list2):
    l = []
    for ee in list1:
        # We consider here that list1 only have pairs
        if ee[0] not in list2 and ee[1] not in list2:
            flat_l = [x for e in l for x in e]
            if ee[0] in flat_l or ee[1] in flat_l:
                for i, e in enumerate(l):
                    if ee[0] in e:
                        l[i].append(ee[1])
                    if ee[1] in e:
                        l[i].append(ee[0])
            else:
                l.append(ee)
    return l

def f(list1,list2,list3):
    l = [[e] for e in list3]
    list1 = join(list1, list2)
    for ee in list1:
        flat_l = [x for e in l for x in e]
        for e in ee:
            if e in flat_l:
                for i in range(len(l)):
                    if e in l[i]:
                        l[i] = list(set(l[i]+ee))
    print(l)

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[13,15]]
list2 = [7,8]
list3 = [1,6,11,13]

f(list1,list2,list3)
# [[1, 4, 5], [6], [11], [13, 15]]

list1 = [[1,4],[4,5],[5,7],[6,7],[9,7],[10,9],[8,10],[8,11],[8,13],[6,8],[20,2],[20,3],[11,14],[14,16],[13,15]]
list2 = [7,8,20]
list3 = [1,2,3,16,15]

f(list1,list2,list3)
# [[1, 4, 5], [2], [3], [16, 11, 14], [13, 15]]