【问题标题】:Find the size of intersection between two lists查找两个列表之间的交集大小
【发布时间】:2020-02-07 05:02:41
【问题描述】:

我正在尝试编写一个函数来返回两个列表之间的公共元素的数量。如果元素在L1 中出现j 次,在L2 中出现k 次,则共享j 和k 元素中的最小值。

例子:

L1 = [1, 2, 3, 4, 5]
L2 = [4, 2]
L3 = [1, 2, 3, 4, 4, 5, 5]
intersection_size ( L1 , L2 ) => 2
intersection_size ( L1 , L3 ) => 5

我的想法是对L1和L2进行升序排序,然后比较每个元素:

def intersection(L1, L2):
    dL1 = L1[:]
    dL2 = L2[:]
    dL1.sort()
    dL2.sort()
    if dL1[1:] == [] or dL2[1:] == []:
        return 0
    if dL1[0] == dL2[0]:
        return 1 + intersection(dL1[1:], dL2[1:])
    elif dL1[0] > dL2[0]:
        return 0 + intersection(dL1, dL2[1:])
    elif dL1[0] < dL2[0]:
        return 0 + intersection(dL1[1:], dL2)

但是,当我测试 intersection([1, 6, 1, 4], [1, 2, 3, 4]) 时,该函数给了我 1 而不是 2。有人可以告诉我哪一部分错了吗?

我创建了dL1 和dL2,因为我希望L1 和L2 保持不变以用于其他目的,并且由于我是初学者,我只能使用基本递归和抽象列表执行此操作的函数。

【问题讨论】:

标签: python list recursion set-intersection


【解决方案1】:

这部分逻辑不正确:

    if dL1[1:] == [] or dL2[1:] == []:
        return 0

基本情况应该是当一个或两个列表为空时。但是当一个或两个列表具有单个元素时,您将返回 0。这是不正确的,因为该元素仍然可能是匹配项,因此交集的大小不会为 0。如果将此条件更改为 dL1 == [] or dL2 == [],那么它可以工作:

>>> intersection(L1, L2)
2
>>> intersection(L1, L3)
5
>>> intersection([1, 6, 1, 4], [1, 2, 3, 4])
2
>>> intersection([1, 1, 1, 2, 2], [1, 1, 2, 2, 2])
4

【讨论】:

    【解决方案2】:

    以下将起作用

    len(set(L1) & set(L3))
    

    如果您不想使用sets,可以执行以下操作:

    def intersection(L1, L2):
        return len([x for x in L1 if x in L2])
    

    【讨论】:

    • 无需转换为列表; len 在片场上运行良好。
    • 它不能很好地工作,根据 OP 的规范,[1, 1, 2] 和 [1, 1, 3] 的预期结果是 2,而你的方法给出了 1。
    • 用户给出的要求为intersection_size ( L1 , L3 ) =&gt; 5
    • 另外,要求是“我只能使用基本的递归和抽象列表函数来做到这一点”。但是这个答案(如果编辑以注意差异)可能很有用,因为其他人不一定有完全相同的要求。
    • 当有重复值时,len([x for x in L1 if x in L2) 将使用 L1 的计数,而不是两个列表的最小计数。
    猜你喜欢
    • 2021-03-18
    • 2022-06-15
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2013-10-12
    • 2013-02-08
    相关资源
    最近更新 更多