Python 大大提高了1段代码的性能
我这里有一些解决挑战问题的代码(如果您需要查看,请询问): 在到达最后一节之前,一切都正常:Python 大大提高了1段代码的性能,python,python-3.x,performance,optimization,Python,Python 3.x,Performance,Optimization,我这里有一些解决挑战问题的代码(如果您需要查看,请询问): 在到达最后一节之前,一切都正常: roads = 0 for i in lis: for j in lis: if sorted([i, j]) not in notAllowed: notAllowed.append(sorted([i, j])) roads += 1 因为在lis中有1000个元素,这个循环基本
roads = 0
for i in lis:
for j in lis:
if sorted([i, j]) not in notAllowed:
notAllowed.append(sorted([i, j]))
roads += 1
因为在
lis
中有1000个元素,这个循环基本上执行1000000次,这使得这个嵌套for循环的执行速度慢了半个小时。有没有人知道我如何加快这部分的速度,因为当我将问题提交到网站时,我遇到了运行时错误,我怀疑这部分代码就是问题所在。问题在于行如果排序([I,j]),不在notAllowed:
中,速度非常慢。
实际上,notAllowed
是一个增长非常快的列表,在列表中查找元素是在线性时间内完成的(列表的大小)。
因此,您的循环的复杂性大约为O(N^4)(N=len(lis))。
使用集合可以使该循环快O(N^2)倍,因为在集合中查找元素可以在恒定的时间内完成(平均)
结果如下:
notAllowedSet = {tuple(e) for e in notAllowed}
roads = 0
for i in lis:
for j in lis:
elem = (min(i, j), max(i, j))
if elem not in notAllowedSet:
notAllowed.append(list(elem))
notAllowedSet.add(elem)
roads += 1
请注意,由于集合不能散列基于列表的对,因此我使用了可以成功散列的基于元组的对(在不允许的中使用元组的对也应该比基于列表的对快)。
此外,集合可能不会保留排序(关于您的python版本),我不知道notAllowed
的排序是否重要。如果notAllowed
的顺序不重要,您可以删除notAllowed
,只处理notAllowedSet
。在这种情况下,可能会对算法进行很多改进(通过排序lis
并避免相对昂贵的集合检查)。python中的100000次迭代当然非常快,这取决于您在这些迭代中所做的工作。既然你正在寻找成员资格,你应该考虑把<代码>不允许的成为一组元组和<代码> i,j< /Cord>是一个元组。另外,使用if-else
ieif(n:=(i,j)代替sorted
如果出于某种原因,这太慢了。你自己试试吧。我确实做了你建议的改进,但是这个代码循环的速度基本上是一样的。不允许一个集合吗?这个集合有多大?我不太确定目的是什么,但检查成员资格似乎相当昂贵。而且,你可以只检查一半的数字.ie适用于范围内的i(len(lis)):适用于范围内的j(i,len(lis))。然后您相应地进行子集。原因是,一旦检查了较高的vmatrix值,就不需要检查较低的矩阵值。即,如果您检查1,2
就不需要检查2,1
它现在是一个列表。大小取决于列表final
我做了它,因此您可以只检查数字,但程序是s直到超级慢。好吧。把它列为一个列表将是非常慢的,因为列表中的成员是O(n)。总之,我想我没有主意了。试着把循环进行一半(不要重复自己)。例如避免1:1000两次
notAllowedSet = {tuple(e) for e in notAllowed}
roads = 0
for i in lis:
for j in lis:
elem = (min(i, j), max(i, j))
if elem not in notAllowedSet:
notAllowed.append(list(elem))
notAllowedSet.add(elem)
roads += 1