简体   繁体   English

in和index函数的列表[Python]

[英]in and index function of list [Python]

I am trying to understand the internal working of the in command and index() of the list data structure. 我试图理解列表数据结构的in命令和index()的内部工作。

When I say: 当我说:

if something not in some_list :
    print "do something"

Is it traversing the whole list internally, similar to a for loop or does it use, better approaches like hashtables etc. 它是在内部遍历整个列表,类似于for循环还是它使用,更好的方法,如hashtables等。

Also the index() in lists, gives an error if the item is not present in the list. 如果列表中不存在该项,则列表中的index()也会出错。 Is the working of both in and index() the same? inindex()的工作是否相同? If index() is better then is it possible to catch the error when an item is not present and if it is possible, is it good programming? 如果index()更好,那么当项目不存在时是否可以捕获错误,如果可能,是否是良好的编程?

Good question! 好问题! Yes, both methods you mention will iterate the list, necessarily. 是的,你提到的两种方法都必须迭代列表。 Python does not use hashtables for lists because there is no restriction that the list elements are hashable. Python不对列表使用哈希表,因为列表元素没有限制可以清除。

If you know about "Big O" notation , the list data structure is designed for O(1) access by looking up a known index, eg my_list[13] . 如果您了解“Big O”表示法 ,则list数据结构是通过查找已知索引(例如my_list[13] )来设计O(1)访问的。 It is O(n) for membership testing. 对于成员资格测试,它是O(n)。

There are other data structures which are optimised for O(1) speed for membership testing (ie __contains__ ), namely set and dict . 还有其他数据结构针对成员资格测试的O(1)速度进行了优化(即__contains__ ),即setdict These are implemented with hashtables . 这些都是用哈希表实现的。

Here is an example of how you can use IPython to verify the time-complexity of sets and lists, to confirm these claims: 下面是一个示例,说明如何使用IPython验证集合和列表的时间复杂度 ,以确认这些声明:

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

For lists, both methods ( in and index() ) iterate over the list to check for the item you're looking for, unfortunately. 对于列表,遗憾的是,这两个方法( inindex() )遍历列表以检查您正在查找的项目。 They will stop iteration as soon as the result of the membership test is known, which means they will iterate to the end if the item is not found. 一旦知道了成员资格测试的结果,它们就会停止迭代,这意味着如果找不到该项,它们将迭代到最后。

As far as I know, if you must work with lists, the not in construct is the most Python and the one you should go with (but you should dump those unnecessary parentheses). 据我所知,如果你必须使用列表,那么not in构造是最常用的Python和你应该使用的那个(但你应该转储那些不必要的括号)。

If you don't need to specifically use a list, the built-in set type can often work in its place. 如果您不需要专门使用列表,则内置类型通常可以在其位置使用。 The set is a data structure similar to the list, but it uses a hashing algorithm to test for the presence of an item, so if you're doing a lot of that kind of work, you may consider switching. 该集合是一个类似于列表的数据结构,但它使用散列算法来测试项目的存在,因此如果您正在进行大量此类工作,则可以考虑切换。 Read the docs I've linked to though, because sets are unordered, so they don't support things like slicing or indexing. 阅读我链接到的文档,因为集合是无序的,因此它们不支持切片或索引等内容。

Yes, you can plan for times when the item you're checking for is not present in your data structure. 是的,您可以计划您正在检查的项目在您的数据结构中不存在的时间。 You're looking for a Try/Except Block : 你正在寻找一个Try / Except块

example_list = [1,2,3]

try:
     index_of_4 = example_list.index(4)
except ValueError:
     print("Oops! 4 wasn't in the list!")

When you know exceptions may occur in your program, you can wrap the offending code in a block like this to gracefully catch and recover from exceptions. 当您知道程序中可能发生异常时,您可以将违规代码包装在这样的块中,以便优雅地捕获异常并从异常中恢复。 It is indeed good programming practice to recover from errors and exceptions as gracefully as you can, even if that means just printing an error message and exiting. 尽可能优雅地从错误和异常中恢复确实是一种很好的编程习惯,即使这意味着只打印错误消息并退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM