列表的交集以旧的方式:无集合且无运算符

时间:2018-08-29 12:24:16

标签: python intersection

作为python用户,这是一个不寻常的问题。一次,我不能使用所有魔术功能和可爱的内置运算符。因此我有点迷路。

我有2到6个包含自定义对象列表的列表。这些对象确实具有方法__eq__,但实际上不适用于此用例。此外,它们是从pickle文件中加载的。因此,我无法修改对象类并重新实现该方法。

L1 = [[Obj1_1, Obj1_2, Obj1_3], [Obj2_1, Obj2_2, Obj2_3], ...]
L2 = [[Obj1_12, Obj1_21, Obj1_33], [Obj2_1, Obj2_2, Obj2_3], ...]
...

正如标题中所述,我正在所有其他列表中寻找L1元素。也就是说,我正在寻找其他子列表列表中存在的对象子列表。

如何定义L1中的对象列表是否与L2中的对象列表相同?

List_of_Obj_in_L1 == List_of_Obj_in_L12 and [elt.s for elt in List_of_Obj_in_L1] == [elt.s for elt in List_of_Obj_in_L2]

知道这些列表很大(上千个元素),如何根据这种条件找到交点?

虚拟示例:

class Dummy:
    def __init__(self, f, s):
        self.f = f
        self.s = s

    def __eq__(self, D):
         return self.f == D.f

    def __ne__(self, D):
         return not self.__eq__(self, D)

L1 = [[Dummy(f, 0) for f in  (20, 30, 20, 50)], [Dummy(f, 0) for f in  (20, 30, 20, 40)], [Dummy(f, k) for k, f in  enumerate((20, 30, 20, 50))], [Dummy(f, 10) for f in  (20, 50)]]

L2 = [[Dummy(f, 0) for f in  (20, 20, 20, 50)], [Dummy(f, 0) for f in  (10, 10, 10, 10)], [Dummy(f, k) for k, f in  enumerate((20, 30, 20, 50))], [Dummy(f, 10) for f in  (20, 50)]]

交叉点将是这两个列表:

Intersect = [[Dummy(f, k) for k, f in  enumerate((20, 30, 20, 50))], [Dummy(f, 0) for f in  (20, 50)]]

现在此示例仅具有两个列表L1和L2。如果我有L1,L2,L3,L4,L5和L6,并且我希望所有元素都存在该怎么办?

我目前正在尝试使用for循环和相等函数:

def equality(L_dummy1, L_dummy2):
    if L_dummy1 == L_dummy2 and [elt.s for elt in L.dummy1] == [elt.s for elt in L.dummy2]:
        return True
    else:
        return False

intersection = list()
for elt in L1:

    in_L2  = False
    for elt2 in L2:
        if equality(elt, elt2):
            in_L2 = True

    in_L3 = False
    for elt2 in L3:
        if equality(elt, elt2):
            in_L3 = True

    if in_L2 and in_L3:
        intersection.append(elt)

还有更好的方法吗?谢谢!

1 个答案:

答案 0 :(得分:2)

您当然可以使用allany缩短它:

def equality(L_dummy1, L_dummy2):
    return  L_dummy1 == L_dummy2 and \
            all(elt1.s==elt2.s for elt1, elt2 in zip(L.dummy1, L.dummy2))

intersection = [
    elt for elt in L1 if all(any(equality(elt, x) for x in l) for l in (L2, L3))
]

equality和交集中,allany的使用保证了迭代的尽早中断。如果您在看到第一个不匹配项时知道它们不相等,则无需构建elt.s的完整列表。

相关问题