二分法定义:给定已按升序排好序的包含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依次遍历,泛用性比较强,但是大大牺牲了效率