在 python 中使用 in 运算符搜索列表时使用啥算法?
Posted
技术标签:
【中文标题】在 python 中使用 in 运算符搜索列表时使用啥算法?【英文标题】: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。 : 当然,list
s 是这样。但对于其他容器并非如此(例如,集合使用哈希表 - 请参阅 setobject.c 第 689 行中的 set_contains_entry()
。)
@Li-aungYip 感谢您的澄清
【参考方案1】:
list
s 不能被假定为已排序(或任何顺序),因此二进制搜索不起作用。也不能假定键是可散列的,因此与 dict
或 set
不同,不能使用散列表查找来加速搜索
据推测,这是从第一个到最后一个元素的直接检查。
我会尝试挖掘相关的 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 list
或 set
中某个元素的成员资格,例如:
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
【讨论】:
哦,非常好。需要明确的是,该特定更改说明似乎是在谈论将常量set
s 转换为 frozenset
s - 我认为常量 list
s 的优化早于此。以上是关于在 python 中使用 in 运算符搜索列表时使用啥算法?的主要内容,如果未能解决你的问题,请参考以下文章