Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 大大提高了1段代码的性能_Python_Python 3.x_Performance_Optimization - Fatal编程技术网

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
ie
if(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