【问题标题】:How to find all elements in B that contain any element of A, where A and B are lists of combinations of different lengths?如何查找 B 中包含 A 的任何元素的所有元素,其中 A 和 B 是不同长度组合的列表?
【发布时间】:2022-01-06 09:53:38
【问题描述】:

假设A = [[0, 1], [1, 2]] 存储来自{0, 1, 2, 3} 的两个2 组合,而B = [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]] 存储来自{0, 1, 2, 3} 的所有可能的3 组合。

如何找到B 中至少包含A 中的2 个组合之一的所有元素?

我想要的输出是C = [[0, 1, 2], [0, 1, 3], [1, 2, 3]],其中[0, 1, 2] 包括[0, 1][1, 2][0, 1, 3] 包括[0, 1][1, 2, 3] 包括[1, 2]

谢谢! (如果答案代码高效快捷,那就太好了,因为我需要为大规模的AB这样做)

我尝试了以下代码:

import numpy as np
import itertools

A = [[0, 1], [1, 2]]
B = []
Cdup = []
rows = range(4)
for combo in itertools.combinations(rows, 3):
    B.append(list(combo))

print(B)

for b in B:
    for a in A:
        if a.issubset(b):
            Cdup.append(b)

C = np.unique(Cdup)

但是有一个错误说list object has no attribute issubset

【问题讨论】:

  • 到目前为止你自己有什么代码?
  • 是否保证每个内部列表都包含唯一值?也就是说,像[0, 1, 1] 这样的重复项是不可能的?
  • @976993 对。没有重复。
  • @9769953 我只包含代码
  • “一个错误,说列表对象没有属性 'issubset'”:如果将内部列表转换为集合,这将起作用(名称“issubset”是一个赠品)。因此我关于重复的问题是:如果没有重复,那么比较集合比比较列表更容易(并且可能更快)。

标签: python list subset


【解决方案1】:

您可以扫描listB 的每个元素b 并检查listA 的任何元素a 是否是b 的子集,在这种情况下保留b

编码:

[b for b in listB if any(set(a).issubset(set(b)) for a in listA)]

【讨论】:

  • 非常感谢。这正是我想要的。
  • 赞成,因为这肯定是最好的解决方案。我试图做类似的事情,但我使用的是运算符in,我认为这是issubset() 方法使用的运算符,但它不起作用(原因很明显)。谢谢你,@iGian。
【解决方案2】:

这是使用itertools.combinations、推导式和set 的解决方案:

from itertools import combinations

A = [(0, 1), (1, 2)]
B = list(combinations(range(4), 3))
C = set(b for a in A for b in B if a in set(combinations(b, len(a))))

print(C)

结果:

{(0, 1, 2), (0, 1, 3), (1, 2, 3)}

上述解决方案假定len(a) <= len(b) 其中ab 分别是AB 的元素。它所做的只是检查A 的每个元素是否是B 的每个元素的组合的一个元素,由A 的元素的len() 组合。

【讨论】:

  • 非常感谢您的回答和解释!这很有帮助。我进一步将 c 从 set 更改为 list 将提供我想要的。
  • 您可以在理解之后将c 转换为列表。需要set 才能删除重复的组合。像c = list(set(... 这样的东西就可以完成这项工作。
  • 我明白了。非常感谢!这很有帮助。
【解决方案3】:

希望此代码可以成为您的方案的解决方案,如果您认为需要任何解释,请告诉我:

listA=[[0,1],[1,2]]
listB=[[0,1,2],[0,1,3],[0,2,3],[1,2,3]]
res = []

for comA in listA:

    strA = " ".join(str(e) for e in comA)

    for comB in listB:
    
        strB = " ".join(str(el) for el in comB)
    
        if strA in strB:
        
            res.append(list(comB))
            # use tuple if you want to remove duplicates easily:
            # res.append(tuple(comB))


print(res)

# if the res list contain tuples the to remove duplicates we can use:
# mylist = list(dict.fromkeys(res))
# print(mylist)

【讨论】:

  • 当心:使用listA = [[0, 2], [0, 3]],您当前的代码将丢失[0, 1, 2][0, 1, 3]。也许集合比字符串更合适......
  • @HosseinKoofi 谢谢。这很有帮助。我想它需要一个额外的步骤:从 res 中删除重复项。
  • @T34driver 通过在 res 中使用元组而不是列表 ==> res.append(tuple(comB)) 然后在全局部分中,您可以通过 ===> mylist = list( dict.fromkeys(res))
  • @HosseinKoofi 我明白了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-02-18
  • 2021-10-06
  • 1970-01-01
  • 2022-08-19
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多