提高大型(一百万个条目)列表中的索引搜索速度

时间:2019-03-09 14:05:25

标签: python search

我有一个列表,它是一百万个项目的随机,可重复整数。我需要对该列表进行排序,然后找到列表中每个唯一元素的第一次迭代的索引。当我这样做时,我的运行时间超过了5分钟。谁能给我任何建议来加速我的代码?下面显示了我的流程示例。

import random

a = []
for x in range(1000000):
    a.append(random.randint(1,10000))
unique_a = set(a)
inds=[0]
inds = [a.index(i) for i in sorted(unique_a) if i not in inds]

3 个答案:

答案 0 :(得分:3)

// Display a label at the location of Google's Sydney office Uri gmmIntentUri = Uri.parse("geo:0,0?q=-33.8666,151.1957(Google+Sydney)"); Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri); mapIntent.setPackage("com.google.android.apps.maps"); startActivity(mapIntent); 是隐式二次的,inds = [a.index(i) for i in sorted(unique_a) if i not in inds]是线性的。使用字典在排序列表上一遍获取索引:

a.index(i)

答案 1 :(得分:3)

只需存储每个唯一元素的第一位置:

public function notifications()
    return Auth::user()->unreadNotifications()->limit(5)->get();
}

然后将first_position = {} for i, value in enumerate(a): if value not in first_position: first_position[value] = i 的{​​{1}}替换为

或仅使用:

a.index(i)

答案 2 :(得分:1)

您可以使用标准库的bisect模块中的bisect_left函数来执行此操作。在经过排序的列表上,二等分搜索比在列表中搜索要快index

>>> L = [random.randint(0, 10) for _ in range(100)]
>>> L.sort()
>>> L.index(9)
83
>>> bisect.bisect_left(L, 9)
83

>>> timeit.timeit(setup="from __main__ import L", stmt="L.index(9)")
2.1408978551626205
>>> timeit.timeit(setup="from __main__ import L;from bisect import bisect_left", stmt="bisect_left(L, 9)")
0.5187544231303036

在我的机器上,使用bisect.bisect_left比遍历列表和按以下方式累加索引要快:

>>> L = [random.randint(0, 100) for _ in range(10000)]
>>> L.sort()
>>> def iterative_approach(list_):
...     unique = set(list_)
...     first_inds = {}
...     for i, x in enumerate(list_):
...         if x not in first_inds:
...             first_inds[x] = i
...     return [first_inds[x] for x in sorted(unique)]
... 
>>> ia = iterative_approach(L)

>>> bisect_left = bisect.bisect_left
>>> def bisect_approach(list_):
...     unique = set(list_)
...     out = {}
...     for x in unique:
...         out[x] = bisect_left(list_, x)
...     return [out[x] for x in sorted(unique)]
... 
>>> ba = bisect_approach(L)
>>> ia == ba
True


>>> timeit.timeit(setup="from __main__ import L, iterative_approach", stmt="iterative_approach(L)")
1488.956467495067
>>> timeit.timeit(setup="from __main__ import L, bisect_approach", stmt="bisect_approach(L)")
407.6803469741717