Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在列表中查找元素的索引。二进制搜索还是使用索引功能?_Python - Fatal编程技术网

Python 在列表中查找元素的索引。二进制搜索还是使用索引功能?

Python 在列表中查找元素的索引。二进制搜索还是使用索引功能?,python,Python,我是python新手,一直在编写一个练习程序,根据400万个单词的列表检查密码。我最初的解决方案是这样的(如果列表中包含密码,则打印为true): 导入系统 从对分导入左对分 脚本,密码,pwlist=sys.argv 密码=密码+“\r\n” l=[行对行打开(pwlist)] l、 必须对sort()#进行排序,才能让对分_工作 打印(密码是的,在第一个示例中,您首先设计一个自己的算法,即二进制搜索 在第二个示例中,您只需使用python内置的list.index()函数 第二种方法更快,因

我是python新手,一直在编写一个练习程序,根据400万个单词的列表检查密码。我最初的解决方案是这样的(如果列表中包含密码,则打印为true):

导入系统 从对分导入左对分 脚本,密码,pwlist=sys.argv 密码=密码+“\r\n” l=[行对行打开(pwlist)] l、 必须对sort()#进行排序,才能让对分_工作
打印(密码是的,在第一个示例中,您首先设计一个自己的算法,即二进制搜索

在第二个示例中,您只需使用python内置的
list.index()
函数

第二种方法更快,因为排序列表的成本:
O(N*log(N))
比线性搜索数组的成本更大:
O(N)


考虑这一点:如果您必须检查多个密码,最好对排序后的列表进行一次排序和存储,然后在排序后的列表上使用二进制搜索。

当数据结构已排序时,使用二进制搜索更好,因为它是在O(log N)中获得的当你对列表进行排序时,你用O(N*logn)进行排序,它比线性搜索O(N)慢。列表的复杂性。
索引方法是O(N)在最坏的情况下,基于它的一个优化函数返回列表中第一个匹配项的索引。因此,这将是更好的方法,请注意,在处理排序列表时,二进制搜索很好

listindex(PyListObject *self, PyObject *args)
{
    Py_ssize_t i, start=0, stop=Py_SIZE(self);
    PyObject *v;

    if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
                                _PyEval_SliceIndex, &start,
                                _PyEval_SliceIndex, &stop))
        return NULL;
    if (start < 0) {
        start += Py_SIZE(self);
        if (start < 0)
            start = 0;
    }
    if (stop < 0) {
        stop += Py_SIZE(self);
        if (stop < 0)
            stop = 0;
    }
    for (i = start; i < stop && i < Py_SIZE(self); i++) {
        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
        if (cmp > 0)
            return PyLong_FromSsize_t(i);
        else if (cmp < 0)
            return NULL;
    }
    PyErr_Format(PyExc_ValueError, "%R is not in list", v);
    return NULL;
}
listindex(PyListObject*self,PyObject*args)
{
Py_ssize_t i,开始=0,停止=Py_大小(自身);
PyObject*v;
如果(!PyArg_ParseTuple(args,“O | O&O&:index”,&v,
_PyEval_切片索引,开始(&S),
_PyEval_(索引和停止))
返回NULL;
如果(开始<0){
开始+=Py_尺寸(自身);
如果(开始<0)
开始=0;
}
如果(停止<0){
停止+=Py_尺寸(自身);
如果(停止<0)
停止=0;
}
对于(i=start;iob\u item[i],v,Py\u EQ);
如果(cmp>0)
将PyLong_从SSIZE_t(i)返回;
否则如果(cmp<0)
返回NULL;
}
PyErr_格式(PyExc_ValueError,“%R不在列表中”,v);
返回NULL;
}
但是在您的第一个代码中,您已经做了很多额外的工作

首先,您不需要使用列表理解来获取文件的所有行,而只需使用
file.readlines()
方法即可。此外,您还有一种排序方法,它使第一行的速度比第二行慢得多


p.S如果你只是想以一种更具python风格的方式来检查成员身份,你可以使用
set
对象来保存你的项目,只需在
操作数中使用
,其顺序是O(1)。

AFAIK
index
只需按顺序遍历列表。O(N)可能比O(N*log(N))排序加O(log(N))更快二进制搜索。顺便问一下,你有没有考虑过用l
打印密码?这样做的一个推论是,如果你希望进行足够的搜索,那么花时间提前对列表进行排序是值得的。(其中“足够”表示大致为O(lg n)次搜索。)稍微迂腐一点的注意:平均情况是O(1)。对于散列冲突的集合,它可能更高,并且(最坏的情况)可能是O(n)(所有项都有相同的散列值)@b对于
集合
我没有说搜索是O(1)。我说的是检查成员资格!
import sys

script, password, pwlist = sys.argv
password = password+"\r\n"

l=[line for line in open(pwlist)] #Note we don't need to sort this time

#Catch the "not in list" exception
try:
    print (password <= l[-1]) and (l[l.index(password)] == password)
except ValueError:
    print "False"
listindex(PyListObject *self, PyObject *args)
{
    Py_ssize_t i, start=0, stop=Py_SIZE(self);
    PyObject *v;

    if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
                                _PyEval_SliceIndex, &start,
                                _PyEval_SliceIndex, &stop))
        return NULL;
    if (start < 0) {
        start += Py_SIZE(self);
        if (start < 0)
            start = 0;
    }
    if (stop < 0) {
        stop += Py_SIZE(self);
        if (stop < 0)
            stop = 0;
    }
    for (i = start; i < stop && i < Py_SIZE(self); i++) {
        int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
        if (cmp > 0)
            return PyLong_FromSsize_t(i);
        else if (cmp < 0)
            return NULL;
    }
    PyErr_Format(PyExc_ValueError, "%R is not in list", v);
    return NULL;
}