假设我有两个功能
def myfunction1(number):
biglist = [1,2,3,4,5,6,7,8,9]
print number*biglist
biglist = [1,2,3,4,5,6,7,8,9]
def myfunction2(number, biglist):
print number*biglist
我用ipython的魔法%timeit来计时:
In [5]: %timeit myfunction2(number, biglist)
1000000 loops, best of 3: 607 ns per loop
In [6]: %timeit myfunction1(number)
1000000 loops, best of 3: 841 ns per loop
这是否意味着每次调用myfunction1时都会重新声明biglist
变量?我猜想在第一次函数调用之后,Python会以某种方式将biglist
变量与函数一起存储,这样就不必在每次调用函数时重新初始化列表。
我不知道Python的内部工作方式,所以我只是在猜测。有人可以解释实际发生的事情吗?
答案 0 :(得分:2)
如果不做一些非常复杂的分析,Python就无法做你的建议。赋值语句只是一个赋值语句,如果我在解释器中键入x=3
两次我希望x在我键入之后就是3而不管我在x之间做了什么......这真的没有什么不同< / p>
说明 - 该功能很容易
def myfunction1(number):
biglist = [1,2,3,4,5,6,7,8,9]
biglist = number*biglist
print biglist
在这种情况下,您想重新分配biglist。
这个过程忽略了biglist是一个不同的变量每次调用的事实 - 你可以让这个func同时在2个线程上执行而且它们是不相关的
答案 1 :(得分:0)
是..它在myfunction1的范围内,在myfunction2中,它在全局范围内,直到程序结束才会结束。一旦myfunction1完成,任何与之关联的变量将被标记为无法访问。每次调用都只会在其范围内创建一个新变量。
- 西
答案 2 :(得分:0)
Python必须在myfunction1()的每个条目上创建一个新列表,并将其分配给'biglist'。
在myfunction2()中,您传递的是对全局范围的“biglist”的引用,因此无法进行复制。
两者之间存在其他微妙的差异。传入该引用会使全局数据对(可能不需要的)干扰开放:
>>> biglist = [ 1,2,3,4,5,6,7,8,9 ]
>>> def myfunction3(mylist):
... mylist[2] = 99
...
>>> biglist
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> myfunction3(biglist)
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
...然而,在函数范围内声明它意味着它每次都重新创建。所以,例如:
>>> def myfunction4():
... mylist = [ 1,2,3,4,5 ]
... print mylist
... mylist[2] = 99
...
>>> myfunction4()
[1, 2, 3, 4, 5]
>>> myfunction4()
[1, 2, 3, 4, 5]
每次调用该函数时,您都会获得一份清新,干净,无瑕疵的列表副本。
那么你如何才能充分利用两个世界?试试这个:
>>> def myfunction5():
... mylist = biglist+[] # Make a private copy
... mylist[4] = 99
...
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
>>> myfunction5()
>>> biglist
[1, 2, 99, 4, 5, 6, 7, 8, 9]
您可以看到全局范围列表未更改。基于此方法的新功能将是:
def myfunction1a(number):
mylist = biglist+[] # Copy-safe version
print number*mylist
如何使用您的基准时间进行比较?我知道在这种情况下你实际上并没有修改你的函数中的“biglist”,但是如果你必须拥有共享的全局数据,并且这个列表只是从头开始构建,那么习惯使用它并不是一个糟糕的范例。一次(然后复制)可能会带来一些性能改进。