python-二分法纯python实现 和 默认list.index方法效率比较

二分法定义:给定已按升序排好序的包含n个元素列表,从找出一特定元素x
准备了一个长1w的列表
data = list(range(10000))

#二分法实现
def BinarySearch(alist,tn,n):
    left=0
    right=n-1
    while left<=right:
        middle=int((left+right)/2)
        if alist[middle]==tn:
            return middle
        if tn>=alist[middle]:
            left=middle+1
        else:
            right=middle-1
    return -1

%timeit BinarySearch(data,500,10000)
5.51 µs ± 260 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit data.index(500)
7.16 µs ± 605 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit BinarySearch(data,5000,10000)
4.7 µs ± 217 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit data.index(5000)
62.6 µs ± 2.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit BinarySearch(data,9500,10000)
3.64 µs ± 205 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit data.index(9500)
120 µs ± 1.84 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
事实证明,查找数字约靠近系列末尾,二分法效率 比 默认方法就好的更多
为此找出了python3.6中list.index该方法的源代码

#C
static PyObject *
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_SliceIndexNotNone, &start,
                                _PyEval_SliceIndexNotNone, &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;
}

由此可见,python中list.index方法,默认是从0到n-1依次遍历,泛用性比较强,但是大大牺牲了效率

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值