【问题标题】:Slow Python set membership tests [closed]慢速 Python 集成员资格测试 [关闭]
【发布时间】:2020-07-25 07:56:01
【问题描述】:

我正在从服务器下载文件,但忽略已经下载的文件,因此为此我将下载文件的名称保存在数据库中,当应用程序启动时,数据库中的文件名列表存储在一组如下图。 然后我在服务器上运行 find 命令并获取要下载的文件列表并进行比较如下:

file_list_for_delta = set() #retrieved from DB

for file_name in file_list: #retrieved this list from server using find command
    if file_name in str(file_list_for_delta):
        return True

问题是每个文件名的比较需要很长时间,数据库中至少有 500000 条记录,每次脚本运行时从服务器检索大约 20000 个文件名。

什么是最有效的方法/我可以用来代替 set() 的数据结构。

【问题讨论】:

  • 在服务器端进行比较,大多数数据库管理系统都为此进行了明确的优化。
  • 到底为什么要在检查成员资格之前将set 转换为字符串?您已经拥有正确的结构来在 O(n) 时间内检查成员,然后通过 在每次迭代 时将其转换为字符串来丢弃它。集合成员资格为 O(1),您正在查看结果,使其成为 O(n)。当字符串转换被抛出时,我什至不确定你当前方法的复杂性
  • set 是最快的。
  • 您当前的解决方案只是偶然的! str(your_set) 是一个用于读取而非搜索的字符串。集合的重点是直接在其中查找项目:if obj in your_set

标签: python python-3.x


【解决方案1】:

您的代码几乎是正确的,但对集合成员资格的测试远没有您编写的那么复杂(而且您的版本只是“偶然工作”)。看看这是否工作得更快 - 它不会在每次搜索文件名时将集合转换为字符串!

file_set = set() #retrieved from DB

for file_name in file_list: #retrieved this list from server using find command
    if file_name in file_set:
        return True

您还会注意到我已经重命名了集合的绑定,因为如果集合变量的名称中包含单词“list”;-) 会产生误导。

你没有向我们展示你是如何从数据库中填充集合的,所以我认为该过程的完整性没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 2012-03-02
    • 2012-11-28
    • 2011-10-29
    相关资源
    最近更新 更多