Python: ValueError: not enough values to unpack (expected 3, got 1)

Python: ValueError: not enough values to unpack (expected 3, got 1)

我对 python 中的多处理库有点陌生。我在 youtube 上看了几个讲座,并从多处理中实现了基本的流程实例。我的问题是,我想利用所有 8 个可用内核来加速我的代码。几天前我在这方面问了一个类似的问题,但无法得出合理的答案。我回去做了彻底的功课,现在在了解了池的基础知识(以及多处理中的其他内容)之后,我有点陷入了一种特殊的境地。我遇到了在 SO 上提出的类似问题,例如这个 - () and (Python multiprocessing pool.map for multiple arguments)。我什至实施了前面提到的解决方案。但是我的代码仍然抛出这个错误-

File "minimal_example_so.py", line 84, in <module>
    X,u,t=pool.starmap(solver,[args])
ValueError: not enough values to unpack (expected 3, got 1)

我的代码看起来像这样-

import time 
ti=time.time()
import matplotlib.pyplot as plt
from scipy.integrate import ode
import numpy as np
from numpy import sin,cos,tan,zeros,exp,tanh,dot,array
from matplotlib import rc
import itertools
from const_for_drdo_mod4 import *
plt.style.use('bmh')
import mpltex
from functools import reduce
from multiprocessing import Pool
import multiprocessing
linestyles=mpltex.linestyle_generator()

def zetta(x,spr,c): 
    num=len(x)*len(c)
    Mu=[[] for i in range(len(x))]
    for i in range(len(x)):
        Mu[i]=np.zeros(len(c))
    m=[]
    for i in range(len(x)):
        for j in range(len(c)):
            Mu[i][j]=exp(-.5*((x[i]-c[j])/spr)**2)

    b=list(itertools.product(*Mu))
    for i in range(len(b)):
        m.append(reduce(lambda x,y:x*y,b[i]))

    m=np.array(m)
    S=np.sum(m)
    return m/S

def f(t,Y,a,b,spr,tim,so,k,K,C):
    x1,x2=Y[0],Y[1]
    e=x1-2
    de=-2*x1+a*x2+b*sin(x1)
    s=de+2*e
    xx=[e,de]
    sold,ti=so,tim
    #import pdb;pdb.set_trace()
    theta=Y[2:2+len(C)**len(xx)]
    Z=zetta(xx,spr,C)
    u=dot(Z,theta)
    Z1=list(Z)
    dt=time.time()-ti
    ti=time.time()
    sodt=(s-sold)/dt
    x1dot=de
    x2dot=-x2*cos(x1)+cos(2*x1)*u
    xdot=[x1dot,x2dot]
    thetadot=[-20*number*(sodt+k*s+K*tanh(s))-20*.1*number2 for number,number2 in zip(Z1,theta)]
    sold=s
    ydot=xdot+thetadot
    return [ydot,u]

def solver(t0,y0,t1,dt,a,b,spr,tim,so,k,K,C):
    num=2
    x,t=[[] for i in range(2+len(C)**num)],[]
    u=[]
    r=ode(lambda t,y,a,b,spr,tim,so,k,K,C: f(t,y,a,b,spr,tim,so,k,K,C)[0]).set_integrator('dopri5',method='bdf')
    r.set_initial_value(y0,t0).set_f_params(a,b,spr,tim,so,k,K,C)
    while r.successful() and r.t<t1:
        r.integrate(r.t+dt)
        for i in range(2+len(C)**num):
            x[i].append(r.y[i])

        u.append(f(r.t,r.y,a,b,spr,tim,so,k,K,C)[1])
        t.append(r.t)
    return x,u,t

if __name__=='__main__':
    spr,C=1.5,[-3,-1.5,0,1.5,3]
    num=2
    k,K=2,5
    tim,so=0,0
    a,b=1,2
    y0,T=[0.1,0],100
    x1=[0 for i in range(len(C)**num)]
    x0=y0+x1
    args=(0,x0,T,1e-2,a,b,spr,tim,so,k,K,C)
    pool=multiprocessing.Pool(3)
    X,u,t=pool.starmap(solver,[args])
    #X,u,t=solver(0,x0,T,1e-2,a,b,spr,tim,so,k,K,C)
    nam=["x1","x2"]
    pool.close()
    pool.join()
    plt.figure(1)
    for i in range(len(X[0:2])): 
        plt.plot(t,X[i],label=nam[i])
        plt.legend(loc='upper right')
    plt.figure(2)
    for i in range(len(X[2:])):
        plt.plot(t,X[i])
    plt.figure(3)
    plt.plot(t,u)
    plt.show()

在这里我想告诉我,我所有的参数要么是纯数字,要么是需要传递给求解器方法的 lists/array 数字。我尝试了几种方法来使用 map 甚至 starmap 将我的参数传递给池,但所有这些都是徒劳的。请帮助,在此先感谢。 PS- 我的代码在没有池的情况下工作得非常好。

您在调用 starmap 时使用的是仅包含一个参数元组的列表。因此,return 值也将是一个包含一个元素的列表 - 元组 return 通过一次调用 solver 编辑。所以你实际上是在说

X, u, t = [(x1, u1, t1)]

这就是您得到异常的原因:您不能将一个值(returned 元组)解包为三个变量。如果您想在此处使用 starmap,您需要执行以下操作:

 [(X,u,t)] = pool.starmap(solver,[args])

相反。但是对于只有一组参数,使用 apply 更有意义,因为它是为单次调用而设计的:

 X,u,t = pool.apply(solver, args)