Python 修改函数中的给定列表
我想给传递给函数的列表分配新值。在Python 修改函数中的给定列表,python,function,multiprocessing,Python,Function,Multiprocessing,我想给传递给函数的列表分配新值。在get\u p\u values的情况下,它可以正常工作,但在“read\u occulation”时则不行(我得到的输出是:[[0]、[0]、[0]、[0]、[0]],而不是[[1,2,3]、[1,2,3]、[1,2,3]) 注意,我将列表矩阵[index]传递给函数read\u occulation的原因是我需要使用Lock的acquire()和release() #!/usr/bin/python # Filename: untitled.py # enc
get\u p\u values
的情况下,它可以正常工作,但在“read\u occulation”时则不行(我得到的输出是:[[0]、[0]、[0]、[0]、[0]],而不是[[1,2,3]、[1,2,3]、[1,2,3])
注意,我将列表矩阵[index]
传递给函数read\u occulation
的原因是我需要使用Lock
的acquire()
和release()
#!/usr/bin/python
# Filename: untitled.py
# encoding: utf-8
from __future__ import division
from multiprocessing import Process
def read_occupation( matrix ):
matrix = [ [1,2,3] ]
def get_p_values( p):
for index,value in enumerate( xrange(0,3,1)):
p[index] = value
def main():
p = [ [0] ] * 3
matrix = [ [0] ] * 4
get_p_values( p )
print p
for index in xrange(0,3,2):
p1 = Process( target=read_occupation, args=( matrix[ index ] ) )
p2 = Process( target=read_occupation, args=( matrix[ index + 1 ] ) )
p1.start()
p2.start()
p1.join()
p2.join()
print matrix
if __name__ == '__main__':
main()
它不起作用的原因有很多 首先,在函数
read_occulation
中,您正在更改局部变量的绑定。原始对象保持不变。相反,在get\u p\u values
中,您正在修改对象([]
操作符调用对象的\uuuuuuu setitem\uuuu
函数来更改内部表示)。在这种情况下,更好的办法是使用适当的对象
如果要在read_occulation
中更改列表的全部内容,可以使用列表拼接运算符指定给整个列表:
def read_occupation(matrix):
matrix[:] = [ [1, 2, 3] ]
顺便说一句,如果调用函数read\u occulation
,调用方可能希望它不会更改其参数。您可能应该将其重命名为update\u occulation
或类似的名称
其次,当您通过乘法创建变量时,您会得到一个列表,其中每个索引都包含对同一项的引用。代码p=[[0]]*3
相当于:
>>> l = [0] # Naming the list for more clarity
>>> p = [ l, l, l ] # Each index points to the same list `l`
第三,Process
类期望其args
参数有一个tuple
(或者实际上是遵循iterable协议的对象)。您传递的不是一个元组,而是一个恰好是一个int
的list
(这就是您得到TypeError
异常的原因)。您需要使用以下语法来传递元组
:
# Please note the comma after the closing bracket, it is important
p1 = Process( target=read_occupation, args=( matrix[ index ], ) )
# In python, the syntax for a tuple is weird for tuple of size < 2
# . tuple of 0 item: ()
# . tuple of 1 item: (1,)
# . tuple of 2 items: (1, 2)
#请注意结束括号后的逗号,它很重要
p1=进程(目标=读取占用,参数=(矩阵[索引],)
#在python中,对于大小小于2的元组,元组的语法很奇怪
# . 0项的元组:()
# . 1项的元组:(1,)
# . 两项元组:(1,2)
第四,使用
multiprocessing.Process
,生成一个执行代码的新进程。您的代码中没有通信(我不知道是否有可能从这个过程返回到原始过程)。因此,原始代码中的变量未被修改。此块具有误导性:
p = [ [0] ] * 3
matrix = [ [0] ] * 4
尝试执行p[0]。追加(0),您将得到:
[[0, 0], [0, 0], [0, 0]]
因为[[0]]*3创建了一个包含三个对象的列表,所有对象都指向同一个列表
更糟糕的是:如果你修复了这个+sylvain所说的,我不确定你的程序是否会工作,因为p1和p2将尝试访问相同的列表。在使用之前,您应该仔细阅读
多处理
文档。这是一个非常棘手的库,充满了令人讨厌的陷阱。除了Sylvain所说的,当然它仍然不起作用,因为一个进程不能修改其父进程的变量。创建新流程时,将复制变量
您可以尝试以下示例
from multiprocessing import Process
def modify(idx, li):
li[idx] = 'hello'
a = [0] * 3
p = Process(target=modify, args=(1, a))
p.start()
p.join()
print a
modify(1, a)
print a
结果将是:
[0, 0, 0]
[0, 'hello', 0]
提供了一种跨多个进程共享Python列表的方法:
from __future__ import division
import multiprocessing as mp
def read_occupation( matrix,i ):
matrix[i]=[1,2,3]
def main():
manager=mp.Manager()
matrix=manager.list([ [0] ] * 4)
for index in xrange(0,3,2):
p1 = mp.Process( target=read_occupation, args=(matrix,index) )
p2 = mp.Process( target=read_occupation, args=(matrix,index+1) )
p1.start()
p2.start()
p1.join()
p2.join()
print matrix
if __name__ == '__main__':
main()
屈服
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
您需要修复此处的缩进,以便我们能够理解代码。@Syivain,我尝试使用matrix.\uuuuuSetItem(切片(0),[1,2,3]),但也确实有效。@Syivain,我测试了您的建议,但无效,我得到以下错误:TypeError:“int”对象不支持项分配(ps,我使用的是python 2.7)@Eagle:只有当参数
矩阵
是一个列表
时,它才会起作用。从您的错误来看,似乎您没有将列表
传递给函数,而是将int
传递给函数。对于“创建了一个新进程”,我的意思是当它从其父进程分叉时。我不知道它是否正确表达了我的意思,对不起:(感谢您的重播,但我的问题有解决方案吗?正如您所介绍的,没有…@Eagle提供了许多解决方案。您可以根据自己的需要修改易晃的代码。如果您不理解答案中的某些内容,请告诉我们。如果您真的想使用流程,我认为unutbu的解决方案可能足够好。我只想假设多进程解决方案可能比单进程解决方案慢得多,如果您想在子进程中执行的操作与您的read\u accountry
一样简单。我想您可以看看该部分。@Yi Huang,这是一个简单的示例,我真正要做的是从文件中读取一些数据,这需要相同的时间(有时到1小时)