首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python子列表在list2中没有元素,在list3中有一个元素

Python子列表在list2中没有元素,在list3中有一个元素
EN

Stack Overflow用户
提问于 2017-05-29 12:46:08
回答 3查看 95关注 0票数 0

我需要用相同的元素对子列表进行分组,子列表中的所有元素在list2中都没有元素,在list3中有一个元素,例如:

代码语言:javascript
运行
复制
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,4,5],它们在list3中包含1,而在list2中不包含7

因此,在链接之后,新的列表应该是:

代码语言:javascript
运行
复制
new_list1 = [[1,4,5],[6],[11],[13,15]]

在一个子列表中不应该有相同的号码,订单也不重要。

还有一个更长的例子:

代码语言:javascript
运行
复制
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]

在链接之后,它将是

代码语言:javascript
运行
复制
new_list = [[1,4,5],[2,3],[11,14,16],[13,15]]

怎样才能一般地做到这一点呢?

编辑最后的算法应该包括以下三个基本步骤:

  1. 删除list1所有子列表中包含在list2中的所有元素。
  2. 加入所有具有公共元素的list1子列表。
  3. 删除不包含任何list1元素的所有list3子列表。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-05-29 14:50:30

以下是我对此的看法,如果托马斯·库恩能正确解读你的想法:

代码语言:javascript
运行
复制
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

至于测试:

代码语言:javascript
运行
复制
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]结果。

更新

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

代码语言:javascript
运行
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2017-05-29 14:03:42

此代码应完成以下工作:

代码语言:javascript
运行
复制
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)])

对于第一个例子,这提供了:

代码语言:javascript
运行
复制
[[1, 4, 5], [6], [11], [13, 15]]

对于第二个例子

代码语言:javascript
运行
复制
[[1, 4, 5], [2], [3], [11, 14, 16], [13, 15]]

希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2017-05-29 13:37:21

首先,从编写join函数开始。我包括了第二个列表,以删除不需要的元素。

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

最后给出了产出。

代码语言:javascript
运行
复制
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]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44242880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档