【问题标题】:in and index function of list [Python]列表的 in 和 index 函数 [Python]
【发布时间】:2014-11-17 01:14:38
【问题描述】:

我正在尝试了解in 命令和列表数据结构的index() 的内部工作原理。

当我说:

if something not in some_list :
    print "do something"

它是在内部遍历整个列表,类似于for 循环还是使用更好的方法,如hashtables 等。

列表中的index() 也会在列表中不存在该项目时给出错误。 inindex() 的工作方式相同吗?如果index() 更好,那么是否有可能在项目不存在时捕获错误,如果可能,是否是好的编程?

【问题讨论】:

  • O(n) 的有趣插图:$ for i in 1 2 3 4 5 ; do python -mtimeit -s "l=range(int(1e$i))" "(-1) not in l" ; done

标签: python python-3.x python-2.7 list data-structures


【解决方案1】:

好问题!是的,您提到的两种方法都必然会迭代列表。 Python 不对列表使用哈希表,因为列表元素是可哈希的没有限制。

如果您了解"Big O" notation,则list 数据结构设计用于通过查找已知索引进行 O(1) 访问,例如my_list[13]。成员资格测试是 O(n)。

还有其他数据结构针对成员资格测试的 O(1) 速度进行了优化(即__contains__),即setdict。这些是用hashtables 实现的。

这是一个示例,说明如何使用 IPython 验证集合和列表的 time-complexity,以确认这些声明:

In [1]: short_list, long_list = range(1000), range(10000)

In [2]: timeit 'potato' not in short_list
10000 loops, best of 3: 40.9 µs per loop

In [3]: timeit 'potato' not in long_list
1000 loops, best of 3: 440 µs per loop

In [4]: small_set, big_set = set(short_list), set(long_list)

In [5]: timeit 'potato' not in small_set
10000000 loops, best of 3: 72.9 ns per loop

In [6]: timeit 'potato' not in big_set
10000000 loops, best of 3: 84.5 ns per loop

【讨论】:

    【解决方案2】:

    对于列表,不幸的是,这两种方法(inindex())都会遍历列表以检查您要查找的项目。一旦知道成员资格测试的结果,它们就会停止迭代,这意味着如果没有找到该项目,它们将迭代到最后。

    据我所知,如果您必须使用列表,not in 构造是最 Python 的构造,也是您应该使用的构造(但您应该丢弃那些不必要的括号)。

    如果您不需要专门使用列表,内置的set 类型通常可以代替它。集合是一种类似于列表的数据结构,但它使用散列算法来测试是否存在项目,因此如果您正在做大量此类工作,您可以考虑切换。不过请阅读我链接到的文档,因为集合是无序的,所以它们不支持切片或索引之类的东西。

    是的,您可以计划您要检查的项目何时不在您的数据结构中。您正在寻找Try/Except Block

    example_list = [1,2,3]
    
    try:
         index_of_4 = example_list.index(4)
    except ValueError:
         print("Oops! 4 wasn't in the list!")
    

    当您知道程序中可能发生异常时,您可以将有问题的代码包装在这样的块中,以便优雅地捕获异常并从异常中恢复。尽可能优雅地从错误和异常中恢复确实是一种很好的编程习惯,即使这意味着只是打印一条错误消息并退出。

    【讨论】:

      猜你喜欢
      • 2016-01-14
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 2015-04-22
      • 2013-06-30
      相关资源
      最近更新 更多