2016-01-13 133 views
0

使用标准语法的Python物资检查元素是否是列表:Python如何检查列表中是否存在元素?

if someElement in someList: 

实际上被在此执行? Python是否循环遍历每一个索引并检查是否相等,或者是更复杂的实现?

我写的程序运行速度非常慢。没有数学正在执行,但它很大程度上依赖于检查项目是否存在于长列表中。有更快速的解决方案吗?

已解决:检查元素是否在列表中与循环遍历每个项目并检查相等性是否相同。但是,由于项目被散列,因此检查集合中的项目会显着加快。

即使在清单中的项目是unhashable(在我的情况,其他列表),它仍然是值得转换为一个字符串,存储在一组,并在需要时转换回。起初,我认为这很笨重,会降低性能。但是,它确实允许我的程序在几分钟之内完成,而之前几天才会完成。

不要低估检查集合中项目的速度。

+0

https://wiki.python.org/moin/TimeComplexity – paxdiablo

回答

4

是的,它遍历每个索引并检查是否相等。

此:

someElement in someList 

等同于:

any(x == someElement for x in someList) 

为了加快速度,你大概可以使用set代替list,但真正取决于元素的类型你集合。

如果列表很大,查找速度会很慢。

+1

切换到一套完美的工作。速度的变化很戏剧化! – Dan

2
nc=set(someList) 
if someElement in nc: #this will now be O(1) rather than O(n) 

您可以制作一份清单,并改善您的表现。

0

是的,Python正在遍历每个索引。 in运营商呼叫__contains__()特殊方法(source)。

我想了列表 - 假设CPython的2 - 它在listobject.c this list_contains code结束了,一个简单的for遍历列表项:

list_contains(PyListObject *a, PyObject *el) 
{ 
    Py_ssize_t i; 
    int cmp; 

    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) 
     cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i), 
              Py_EQ); 
    return cmp; 
} 

有没有更快速的解决方案吗?

使用容器的查找速度更快 - @ vks表示一个集合,字典也很常见。两者都取决于您的数据可与hash(item)排除,否则他们无法工作。

但数据结构和它们不同的性能特征的研究是太大了一个答案,尤其是对你的任务是什么没有细节,并没有给出代码,并没有给定的性能。树结构也可以有更快的查找速度,但是如果你能找到一个,那么将工作转移到用C语言编写的现有库是一个很好的Python策略。