修改了函数内的给定列表

时间:2011-08-31 15:46:34

标签: python function multiprocessing

我想将新值分配给我传递给我的函数的列表。在get_p_values的情况下,它工作正常,但在`read_occupation'没有(我得到输出:[[0],[0],[0],[0]]而不是[[1,2] ,3],[1,2,3],[1,2,3],[1,2,3]])。

备注,我传递给read_occupation列表matrix[ index ]的原因是,我需要使用acquire()的{​​{1}}和release()

Lock

4 个答案:

答案 0 :(得分:3)

除了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]

答案 1 :(得分:2)

有很多原因导致它无效。

首先,在函数read_occupation中,您正在更改局部变量的绑定。原始对象保持不变。相反,在get_p_values中,您正在修改对象([]运算符调用更改内部表示的对象的__setitem__函数)。在这种情况下更好的想法是使用适当的对象。

如果要更改read_occupation中列表的整个内容,可以使用列表拼接运算符分配到整个列表:

def read_occupation(matrix):
    matrix[:] = [ [1, 2, 3] ]

顺便说一句,如果你叫你函数read_occupation,调用者可能会期望它不会改变它的参数。您应该将其重命名为update_occupation或类似的东西。

其次,当您通过乘法创建变量时,会得到list,其中每个索引都包含对同一项的引用。代码p = [ [0] ] * 3相当于:

>>> l = [0]          # Naming the list for more clarity
>>> p = [ l, l, l ]  # Each index points to the same list `l`

第三,Process类期望其tuple参数args(或实际上是可迭代协议之后的对象)。你没有传递一个元组,而是一个恰好是一个list int的项目(这就是你得到TypeError例外的原因)。您需要使用以下语法来传递tuple

# 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)

第四,使用multiprocessing.Process生成一个执行代码的新进程。您的代码中没有回传(我不知道是否可以从此过程回传到原始过程)。因此原始代码中的变量不会被修改。

答案 2 :(得分:1)

mp.Manager提供了一种跨多个流程共享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]]

答案 3 :(得分:0)

这个区块具有误导性:

p         = [ [0] ] * 3 
matrix    = [ [0] ] * 4

尝试做p [0] .append(0),你会得到:

[[0, 0], [0, 0], [0, 0]]

因为[[0]] * 3创建了一个三个对象的列表,所有这些对象都指向同一个列表。

更糟糕的是:如果你解决了这个问题,我不确定你的程序是否有用+ sylvain所说的,因为p1和p2会尝试访问同一个列表。在使用之前,您应该仔细阅读multiprocessing doc。这是一个非常棘手的lib,充满了讨厌的陷阱。