【问题标题】:Python most efficient data structure to hold values and check if a value exist [duplicate]Python最有效的数据结构来保存值并检查值是否存在[重复]
【发布时间】:2021-03-20 10:08:59
【问题描述】:

假设我有数百万个字符串 ID,我想将它们存储在一个变量中并检查是否存在一个 ID,我可以想到两种方法,listdict

使用list

>>> timeit_a = timeit.Timer('"9999999" in a', setup='a = [str(i) for i in range(3000000)]')
>>> timeit_a.timeit(1)
0.06293477199994868

使用dict

>>> timeit_b = timeit.Timer('"9999999" in b', setup='b = {str(i): None for i in range(3000000)}')
>>> timeit_b.timeit(1)
3.860999981952773e-06  # equal to 0.00000386099

正如我们所见,使用dict 要快得多,但我觉得使用一堆Nones 创建dict 只是为了利用键的哈希图并不是很优雅。

有没有更规范、更优雅的方式来做到这一点?

【问题讨论】:

  • 感谢 dup 的建议,因为我一生都找不到那个帖子。
  • 是的,使用set 将是执行此操作的规范方式(在底层实现为哈希集)

标签: python


【解决方案1】:

如果您没有值,请使用set(),而不是字典

{str(i) for i in range(30000)}

如果您有数百万个项目,例如,也许卸载到 Redis 会更好地考虑应用程序的内存使用/性能

【讨论】:

  • 太棒了,谢谢!没想到!
  • 我建议使用实际的 set 理解,而不是围绕生成器表达式的 set() 构造函数。 {str(i) for i in range(30000)} 将运行得更快(它避免了保存和恢复生成器状态的开销)。 set(map(str, range(30000))) 可能比这更快,但最好不要鼓励 map 获得微不足道的收益(它只在特殊情况下提供收益;任何时候你必须使用理解可以内联的 lambda 都是一种悲观)。
【解决方案2】:

一定要使用set。它就像一个dict,但没有值,因为它不是一个映射而是一个...集合,令人惊讶。

a = {str(i) for i in range(300000)} # one way of initializing a set
a = set()
for i in range(3000000):
    a.add(str(i)) # another way

【讨论】:

  • sets 没有 append 方法。大概你的意思是add
  • @ShadowRanger 绝对,谢谢,已修复
【解决方案3】:

你想要一个set。一个集合基本上是一个没有值的dict。它是一组具有dict 查询性能的项目集合,用于询问集合中是否有东西。

timeit_b = timeit.Timer('"9999999" in b', setup='b = {str(i) for i in list(range(3000000))}')
timeit_b.timeit(1)

【讨论】:

    猜你喜欢
    • 2019-07-30
    • 2017-09-25
    • 2015-01-18
    • 1970-01-01
    • 2017-11-24
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    相关资源
    最近更新 更多