【问题标题】:What algorithm is used when using the in operator in python to search a list?在 python 中使用 in 运算符搜索列表时使用什么算法?
【发布时间】:2012-05-15 03:46:30
【问题描述】:

当使用“in”运算符搜索列表中的项目时,例如

if item in list:
  print item

使用什么算法来搜索这个项目。是从头到尾直接搜索列表还是使用二进制搜索之类的方法?

【问题讨论】:

  • in,按顺序遍历项目,没有搜索
  • @RC。 : 当然,lists 是这样。但对于其他容器并非如此(例如,集合使用哈希表 - 请参阅 setobject.c 第 689 行中的 set_contains_entry()。)
  • @Li-aungYip 感谢您的澄清

标签: python algorithm search operators


【解决方案1】:

lists 不能被假定为已排序(或任何顺序),因此二进制搜索不起作用。也不能假定键是可散列的,因此与 dictset 不同,不能使用散列表查找来加速搜索

据推测,这是从第一个到最后一个元素的直接检查。

我会尝试挖掘相关的 Python 源代码。

--

编辑:实现in 运算符的Python list.__contains__() 函数在listobject.c 中定义:

   393 static int
   394 list_contains(PyListObject *a, PyObject *el)
   395 {
   396     Py_ssize_t i;
   397     int cmp;
   398 
   399     for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
   400         cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
   401                                            Py_EQ);
   402     return cmp;
   403 }

它遍历列表中的每个元素,从第一个元素到最后一个元素(或直到找到匹配项。)这里没有捷径。

--

编辑 2:情节变厚了。如果 Python 检测到您正在测试 constant listset 中某个元素的成员资格,例如:

if letter in ['a','e','i','o','u']:    # list version
if letter in {'a','e','i','o','u'}:    # set version

编辑 3 [@JohnMachin]:

常量列表在 2.5-2.7 和 3.1-3.3 中优化为常量元组
常量集在 3.3 中优化为(常量)frozenset。

另见@CoryCarson 的回答。

【讨论】:

  • 常量列表在 2.5-2.7 和 3.1-3.3 中优化为常量tuple
  • @JohnMachin:所以不是针对in 运算符的哈希表查找?请随时编辑我的答案以确保准确性。
【解决方案2】:

如果list 是文字列表,Python 3.2+ 将采用更快的方法:http://docs.python.org/dev/whatsnew/3.2.html#optimizations

【讨论】:

  • 哦,非常好。需要明确的是,该特定更改说明似乎是在谈论将常量 sets 转换为 frozensets - 我认为常量 lists 的优化早于此。
猜你喜欢
  • 1970-01-01
  • 2016-03-03
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多