通过__getitem __()触发时,python的in函数如何工作?

时间:2018-07-25 13:57:31

标签: python membership

The official documentation表示python首先尝试通过__contains__()进行检查,然后通过__iter__(),最后是__getitem__()进行检查,具体取决于定义的函数,以便解析{ {1}}个电话。 例如:

in

链接的文档表明,如果存在任何非负索引if y in x: print("y present in x") else: print("y not present in x") ,例如i,则结果为x[i] == y,否则为True。 如何对所有False进行搜索?对“所有”正数进行线性遍历似乎是不可能的。线性遍历必须存在一定范围(对于列表,它应该为0到len())。如何确定这些界限?

5 个答案:

答案 0 :(得分:2)

这些特殊方法的目的是为数据结构的设计者 you 提供一种以适合您情况的快速方式执行查找的方法。例如,您可以从list派生一个通过反向索引增强的类,以便按值快速查找。 (显然,这会减慢插入速度,因为需要更新索引,但是让我们假设您将进行大量查找,因此您知道这是值得的。)

如果您的类无法改善默认访问权限,则无需定义特殊方法。 Python将依靠所有可用方法,包括顺序搜索。

答案 1 :(得分:2)

Aaah,我想知道...您想知道如何获取 key 来遍历既没有__contains__()也没有{{1 }}-很简单,它可以使用线性迭代工作,直到遇到IndexError,如文档所述:

  

...如果一个类定义了__iter__(),则且仅当存在一个非负整数索引__getitem__()时,x in y就是Truei }和所有较低的整数索引都不会引发x == y[i]异常。 (如果引发了任何其他异常,就好像引发了该异常一样)

关键点:

IndexError

答案 2 :(得分:1)

  

它如何对所有此类i进行搜索?

这在很大程度上取决于要在其中执行搜索的对象的数据结构。例如,如果您有一个list对象,则成员资格检查的复杂度为O(n),并且如果您有一个使用哈希表访问其项(__getitem__属性)(例如字典或集合)的数据结构复杂度约为O(1)。

因此,通常,对于用户定义的对象,它的工作方式与文档中所述的相同。对于没有哈希表的对象,它是线性搜索;对于带有哈希表的对象,它是常量搜索。

答案 3 :(得分:1)

没有__contains____iter__的对象的迭代发生here。序列扫描发生here。使用__contains__或回退到迭代的决定发生在here

答案 4 :(得分:0)

这就是它的工作原理。这是使用@url = job_parse_page.at_css("h2 a")['href'] 的演示:

s/\\n/[\\r\\n]+/g

您可以看到时间复杂度与容器大小成正比。