【问题标题】:Optimal check if the elements of a list are in another list in python最佳检查列表的元素是否在python中的另一个列表中
【发布时间】:2021-04-30 12:57:41
【问题描述】:

我需要检查一个列表中的项目是否在另一个列表中。两个列表都包含文件的路径。

    list1 = [a/b/c/file1.txt, b/c/d/file2.txt]
    list2 = [a/b/c/file1.txt, b/c/d/file2.txt, d/f/g/test4.txt, d/k/test5.txt]

我尝试了类似的方法:

    len1 = len(list1)
    len2 = len(list2)

    res = list(set(list2) - set(list1))
    len3 = len(res)

    if len2 - len1 == len3:
        print("List2 contains all the items in list1")

但这不是最佳选择,我有超过 50k 项的列表。我认为一个好的解决方案可以是创建一个哈希表,但我不知道如何构建它。有什么建议可以留言。

【问题讨论】:

  • 这里有什么问题?为什么你觉得集合不是最理想的?

标签: python python-3.x algorithm hashtable


【解决方案1】:

Python sets 基于散列,因此您不能将不可散列的对象放入 sets 中。 而是计算长度,直接执行set difference

>>> list1 = ['a/b/c/file1.txt', 'b/c/d/file2.txt']
>>> list2 = ['a/b/c/file1.txt', 'b/c/d/file2.txt', 'd/f/g/test4.txt', 'd/k/test5.txt']
>>> if (set(list1) - set(list2)):  # will return empty set (Falsy) if all are contained
        print("List2 contains all the items in list1")

List2 contains all the items in list1

这是细分:

>>> difference = set(list1) - set(list2)
>>> difference
set()
>>> bool(difference)
False

【讨论】:

    【解决方案2】:

    我认为一个好的解决方案是创建一个哈希表,但我不知道如何构建它。

    集合已经实现using hash tables,所以你已经在这样做了。

    假设您没有(或不关心)重复项,您可以尝试:

    list1 = [1,2,3]
    list2 = [1,2,3,4]
    set(list1).issubset(list2)
    

    请注意如何无需将 list2 转换为集合,请参阅 this answer 上的 cmets。

    编辑:您的解决方案和我的解决方案都是 O(n) 平均值,不会比这更快。但是您的解决方案可以避免一些操作,例如将差异 res 转换为列表以获取其大小。

    【讨论】:

    • 如果我需要知道不在其他列表中的项目怎么办?
    • 然后你可以使用set(list2).difference(list1),它将返回一个集合,其中包含list2中但不在list1中的所有内容。
    猜你喜欢
    • 1970-01-01
    • 2021-08-24
    • 2022-01-06
    • 1970-01-01
    • 2012-08-01
    • 2021-04-14
    • 2021-12-13
    • 2019-09-28
    • 2017-02-05
    相关资源
    最近更新 更多