如果我有一个包含 300k 个元素的长未排序列表,是否会先对该列表进行排序,然后在列表上执行“for”循环以加快代码速度?无论如何,我都需要做一个“for循环”,不能使用列表理解。
sortedL=[list].sort()
for i in sortedL:
(if i is somenumber)
"do some work"
我如何向 python 发出 sortedL 已排序而不是读取整个列表的信号。对列表进行排序有什么好处吗?如果有那么我该如何实施?
您似乎正在考虑对列表进行排序,以便您可以快速查找somenumber
.
排序是否值得取决于您是要搜索一次还是重复搜索:
如果您只搜索一次,对列表进行排序不会加快速度。只需遍历列表以查找元素,就完成了。
另一方面,如果您需要重复搜索值,请务必对列表进行预排序。这将使您能够用于bisect
快速查找值。
第三种选择是将元素存储在dict
. 这可能会提供最快的查找,但可能会比使用列表的内存效率低。
for
python中循环的成本不取决于输入数据是否排序。
话虽如此,如果您先排序,您可能能够提前break
退出for
循环或在算法级别保存其他计算。
如果要在 sorted 中进行搜索list
,则需要一种利用排序的算法。
一种可能性是内置bisect
模块。这使用起来有点麻烦,但是文档中有一个用于在其之上构建简单排序列表函数的方法。
有了这个食谱,你可以这样写:
i = index(sortedL, somenumber)
当然,如果您只是为了加快单个搜索的速度而进行排序,这有点愚蠢。排序需要 O(N log N) 时间,然后搜索需要 O(log N),总共需要 O(N log N);仅进行线性搜索将花费 O(N) 时间。因此,除非您通常在同一个列表上进行 log N 次搜索,否则这是不值得的。
如果您实际上不需要排序,只需要快速查找,则可以使用 aset
而不是 a list
。这使您可以 O(1) 查找除病理情况外的所有情况。
Also, if you want to keep a list sorted while continuing to add/remove/etc., consider using something like blist.sortedlist
instead of a plain list.