【问题标题】:Python - convert list into dictionary in order to reduce complexityPython - 将列表转换为字典以降低复杂性
【发布时间】:2017-02-27 04:42:07
【问题描述】:

假设我有一个很大的清单:

word_list = [elt.strip() for elt in open("bible_words.txt", "r").readlines()] 

//complexity O(n) --> proporcional to list length "n"

我了解到用于构建dictionarieshash function 可以让lookup 更快,如下所示:

word_dict = dict((elt, 1) for elt in word_list) 

// complexity O(l) ---> constant.

使用word_list,有没有推荐的最有效的方法来降低我的代码的复杂性?

【问题讨论】:

  • 在这种情况下,您最好使用set 而不是dict{elt.strip() for elt in ...}(除非您确实需要一些数据与密钥相关联)。跨度>

标签: python list dictionary asymptotic-complexity


【解决方案1】:

问题中的代码只做一件事:将文件中的所有单词填充到列表中。复杂度是 O(n)。

将相同的单词填充到任何其他类型的容器中仍然至少具有 O(n) 复杂度,因为它必须从文件中读取所有单词并且必须将所有单词放入容器中。

dict 有什么不同?

找出某个东西是否在list 中具有O(n) 复杂度,因为算法必须逐项遍历列表并检查它是否是查找的项。该项目可以在位置 0 找到,这很快,或者它可能是最后一个项目(或根本不在列表中),这使得它成为 O(n)。

dict 中,数据被组织在“buckets” 中。当键:值对保存到dict 时,会计算键的hash,并使用该数字来标识存储数据的bucket。稍后,当查找密钥时,再次计算hash(key) 以识别存储桶,然后仅搜索该存储桶。每个bucked通常只有一个key:value对,因此搜索可以在O(1)中完成。

更多详情,请参阅the article about DictionaryKeys on python.org

set 怎么样?

集合类似于只有键而没有值的字典。该问题包含以下代码:

word_dict = dict((elt, 1) for elt in word_list) 

这显然是一个不需要值的字典,所以一个集合会更合适。

顺便说一句,没有必要先创建一个列表word_list,然后将其转换为setdict。第一步可以跳过:

set_of_words = {elt.strip() for elt in open("bible_words.txt", "r").readlines()}

有什么缺点吗?

总是;)

  • 集合没有重复项。因此,计算一个单词在集合中出现的次数永远不会返回 2。如果需要,请不要使用集合。

  • 一组未排序。没有办法检查哪个是集合中的第一个单词。如果需要,请不要使用集合。

  • 保存到集合的对象必须是可散列的,这意味着它们是不可变的。如果可以修改对象,那么它的 hash 会改变,所以它会在错误的存储桶中并且搜索它会失败。无论如何,strintfloattuple 对象是不可变的,所以至少它们可以进入集合。

  • 写入 到集合可能会比写入列表要慢一些。仍然是 O(n),但是更慢的 O(n),因为它必须计算散列并组织到桶中,而列表只是一个接一个地转储一个项目。请参阅下面的时间安排。

  • 从集合中读取所有内容也会比从列表中读取所有内容要慢一些。

所有这些都适用于dict 以及set

一些计时例子

写入列表与集合:

>>> timeit.timeit('[n for n in range(1000000)]', number=10)
0.7802875302271843
>>> timeit.timeit('{n for n in range(1000000)}', number=10)
1.025623542189976

从列表与集合中读取:

>>> timeit.timeit('989234 in values', setup='values=[n for n in range(1000000)]', number=10)
0.19846207875508526
>>> timeit.timeit('989234 in values', setup='values={n for n in range(1000000)}', number=10)
3.5699193290383846e-06

因此,写入集合似乎慢了大约 30%,但是当有数千个项目时,在集合中找到一个项目的速度要快数千倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2022-11-29
    • 2019-11-18
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多