解决Python中使用map函数报错

在Matlab中运行Bat文件(文件中的内容是运行python脚本的指令),报错如下:

这个错误表明在尝试使用 map(float, last_line.split()) 解压缩值时,得到的值的数量少于期望的数量。具体而言,期望得到3个值(c、g、rate),但是在 last_line.split() 中没有足够的元素。 

涉及到错误的有关代码如图所示:

有关easy.py的具体文件可以我的这篇文章:

关于LibSVM中easy.py文件的解读-CSDN博客,已经对该文件进行了较为详细的解析。

下面我先来介绍一下Python中关于map函数的使用:

map() 函数是 Python 内置函数之一,用于将一个函数应用于可迭代对象(比如列表)的每个元素,返回一个结果迭代器。基本语法如下:

map(function, iterable, ...)
  • function: 要应用于每个可迭代元素的函数
  • iterable: 要迭代的一个或多个可迭代对象

map() 函数将指定的函数应用于可迭代对象中的每个元素,返回一个可迭代对象,其中包含了函数应用后的结果。map()返回的是一个迭代器,需要查看结果,可以将返回的可迭代对象转换为列表、元组等其他类型。 

以下是一个简单的例子,将一个列表中的每个数字平方:

# 定义一个函数,用于计算平方
def square(x):
    return x ** 2

# 创建一个列表
numbers = [1, 2, 3, 4, 5]

# 使用 map() 函数将 square 应用于列表中的每个元素
squared_numbers = map(square, numbers)

# 将结果转换为列表并打印
print(list(squared_numbers))

输出结果将是 [1, 4, 9, 16, 25],即每个数字都被平方了。

好了,以上就是关于map函数使用的介绍了!

我们回到报错的内容上来看,报错内容意思是在使用函数 map 解压缩值时,得到的值的数量少于期望的数量,期望得到3个值(c、g、rate),但是在 last_line.split() 中没有足够的元素。

为了解决这个问题,我们可以添加一些检查确保 last_line.split() 返回的列表包含足够的元素。例如:

last_line = "1.2 3.4 5.6"  # 用你的实际数据替代这个示例字符串

# 检查分割后的元素数量是否足够
split_values = last_line.split()

if len(split_values) >= 3:
    c, g, rate = map(float, split_values)
    # 在这里使用 c、g、rate 变量进行后续的操作
    print("c:", c)
    print("g:", g)
    print("rate:", rate)
else:
    print("Error: Not enough values to unpack.")

这样的检查可以防止在元素不足时尝试解压缩值,从而避免 ValueError。确保在实际使用时,last_line 包含了足够的数值,并且按照期望的格式进行分割。

将上述代码加入到我的代码中,如图所示:

运行结果如图所示:

所以现在我们需要去检查last_line分割后的内容具体是什么。

在easy.py文件中添加如上图所示的代码后,运行结果如下图所示:

通过运行结果我们可以知道last_line.split()的内容为空,这说明last_line是一个空的变量。

继续追溯错误的来源,可以发现last_line是由line赋值得到的,line是通过读取文件对象f获得的,所以我们需要深入去检查一下文件对象f是否为空或者是读取是否有问题。

在这里,Popen 函数创建了一个子进程来执行指定的命令,并且通过 stdout=PIPE 参数捕获了子进程的标准输出。然后,通过 .stdout 属性获取了这个标准输出的文件对象,并将它赋值给了变量 f,f 是文件对象。

因此,通过 f 可以读取子进程的标准输出。可以使用 f.read() 方法来读取子进程的输出内容,或者使用其他文件对象的方法来处理这个输出。例如,可以逐行读取输出,或者按照需要进行其他处理。

注意:对于使用 Popen 创建的子进程,一定要在使用完毕后及时关闭,以避免资源泄漏, 可以使用 f.close() 来关闭这个文件对象。

下面先来判断一下这个文件对象f是否为空对象:

运行结果如图所示,文件对象f是空的

还可以通过对文件对象f进行读取,可以看到f的内容为:b' ',这表示标准输出流为空字节字符串。

这可能有几种原因:

  1. 外部命令没有产生输出: 执行的外部命令可能并没有在标准输出流中输出任何内容。这可能是因为命令成功执行,但是没有产生输出,或者命令执行失败,没有生成任何输出。

  2. 命令执行出错: 如果外部命令执行时发生错误,标准输出流可能为空。你可以通过检查命令的返回代码来确定是否发生了错误。如果返回代码不为零,表示命令执行出错。

下面我们来检查返回代码:

from subprocess import Popen, PIPE

cmd = '{0} -svmtrain "{1}" "{2}"'.format(grid_py, svmtrain_exe, scaled_file)

print("cmd:", cmd)
print('Cross validation...')
f = Popen(cmd, shell=True, stdout=PIPE)
output, error = f.communicate()

return_code = f.returncode

print("Return Code:", return_code)
print("Output:", output)
print("Error:", error)

如果 return_code 不为零,可能需要进一步检查外部命令的错误信息,它通常可以通过标准错误流获取 。这样可以帮助了解外部命令执行时是否发生了错误以及错误的具体信息。

注意:这里的

f = Popen(cmd, shell=True, stdout=PIPE).stdout

改为了  f = Popen(cmd, shell=True, stdout=PIPE)

但是如果要想使用  f.readline() 读取文件对象f中的内容,那么需要改为原来的 f = Popen(cmd, shell=True, stdout=PIPE).stdout, 注意两者的区别! ! !

运行我的代码后,结果如下图所示:

通过运行结果可以看到,输出的 return_code 为 0,可以初步判定外部命令的执行没有问题。同时打印标准输出 output 和标准错误 error 的内容,可以看到这两个变量的值为空,说明命令在执行时没有产生输出和错误。

/*  下面的这段解释是错误的,参数是正确传进去的,命令行字符串的运行是正确的

花了我大半个中午的时间寻找为什么文件对象f是空的,明明一切都很符合逻辑,检查了传入函数的可执行文件都是存在的,scaled_file也是存在的,并且内容不为空。很是想不明白文件对象f为空的原因。后来,我进入到文件grid.py(在前面grid_py被设置为grid.py文件所在的路径)中,经过不断地调试该文件终于终于发现了问题。

最终发现是这段代码出的问题,虽然在这段代码中构建了一个cmd,按理说是给文件grid.py传入参数grid_py、svmtrain_exe、gnuplot_exe以及scaled_file这四个参数,但是实际上只传给了文件grid.py一个参数,通过下图对grid.py文件的调试结果可以看出,只传进去了一个参数。

*/

经过两天的时间,最后我发现是脚本文件grid.py没有提供返回值。如下图所示,虽然调用了函数find_parameters,该函数定义如图所示,但是调用函数处没有接收返回值的变量,所以启动新进程,运行 脚本文件grid.py 后的标准输出值为空值,即 文件对象f 的值为 b' ' 。

函数find_parameters的定义:

def find_parameters(dataset_pathname, options=''):

    def update_param(c,g,rate,best_c,best_g,best_rate,worker,resumed):
        if (rate > best_rate) or (rate==best_rate and g==best_g and c<best_c):
            best_rate,best_c,best_g = rate,c,g
        stdout_str = '[{0}] {1} {2} (best '.format\
            (worker,' '.join(str(x) for x in [c,g] if x is not None),rate)
        output_str = ''
        if c != None:
            stdout_str += 'c={0}, '.format(2.0**best_c)
            output_str += 'log2c={0} '.format(c)
        if g != None:
            stdout_str += 'g={0}, '.format(2.0**best_g)
            output_str += 'log2g={0} '.format(g)
        stdout_str += 'rate={0})'.format(best_rate)
        print(stdout_str)
        if options.out_pathname and not resumed:
            output_str += 'rate={0}\n'.format(rate)
            result_file.write(output_str)
            result_file.flush()

        return best_c,best_g,best_rate

    options = GridOption(dataset_pathname, options)
    print(f"经过改变后options为:{options}")

    # if options.gnuplot_pathname:
    #     gnuplot = Popen(options.gnuplot_pathname,stdin = PIPE,stdout=PIPE,stderr=PIPE).stdin
    # else:
    #     gnuplot = None

    # put jobs in queue

    jobs,resumed_jobs = calculate_jobs(options)
    job_queue = Queue(0)
    result_queue = Queue(0)

    for (c,g) in resumed_jobs:
        result_queue.put(('resumed',c,g,resumed_jobs[(c,g)]))

    for line in jobs:
        for (c,g) in line:
            if (c,g) not in resumed_jobs:
                job_queue.put((c,g))

    # hack the queue to become a stack --
    # this is important when some thread
    # failed and re-put a job. It we still
    # use FIFO, the job will be put
    # into the end of the queue, and the graph
    # will only be updated in the end

    job_queue._put = job_queue.queue.appendleft

    # fire telnet workers

    # if telnet_workers:
    #     nr_telnet_worker = len(telnet_workers)
    #     username = getpass.getuser()
    #     password = getpass.getpass()
    #     for host in telnet_workers:
    #         worker = TelnetWorker(host,job_queue,result_queue,
    #                  host,username,password,options)
    #         worker.start()
    #
    # # fire ssh workers
    #
    # if ssh_workers:
    #     for host in ssh_workers:
    #         worker = SSHWorker(host,job_queue,result_queue,host,options)
    #         worker.start()

    # fire local workers

    for i in range(nr_local_worker):
        worker = LocalWorker('local',job_queue,result_queue,options)
        worker.start()

    # gather results

    done_jobs = {}

    if options.out_pathname:
        if options.resume_pathname:
            result_file = open(options.out_pathname, 'a')
        else:
            result_file = open(options.out_pathname, 'w')


    db = []
    best_rate = -1
    best_c,best_g = None,None

    for (c,g) in resumed_jobs:
        rate = resumed_jobs[(c,g)]
        best_c,best_g,best_rate = update_param(c,g,rate,best_c,best_g,best_rate,'resumed',True)

    for line in jobs:
        for (c,g) in line:
            while (c,g) not in done_jobs:
                (worker,c1,g1,rate1) = result_queue.get()
                done_jobs[(c1,g1)] = rate1
                if (c1,g1) not in resumed_jobs:
                    best_c,best_g,best_rate = update_param(c1,g1,rate1,best_c,best_g,best_rate,worker,False)
            db.append((c,g,done_jobs[(c,g)]))
        # if gnuplot and options.grid_with_c and options.grid_with_g:
        #     redraw(db,[best_c, best_g, best_rate],gnuplot,options)
        #     redraw(db,[best_c, best_g, best_rate],gnuplot,options,True)


    if options.out_pathname:
        result_file.close()
    job_queue.put((WorkerStopToken,None))
    best_param, best_cg  = {}, []
    if best_c != None:
        best_param['c'] = 2.0**best_c
        best_cg += [2.0**best_c]
    if best_g != None:
        best_param['g'] = 2.0**best_g
        best_cg += [2.0**best_g]
    print('{0} {1}'.format(' '.join(map(str,best_cg)), best_rate))
    #
    return best_rate, best_param
   #  return best_c, best_g,best_rate

可以看到find_parameters是有返回值的,但是在调用该函数的地方没有变量接收返回值。

如果调用一个函数并且该函数有返回值,但是在调用函数的地方没有变量接收这个返回值,那么函数执行完毕后其返回值会被丢弃。在这种情况下,即使函数有返回值,但在调用处并没有变量来接收这个返回值,因此这个返回值就无法在后续的代码中被使用或引用。

所以,我想这就是执行命令字符串cmd后文件对象f 为空的原因!!!

下面我再来举个简单的例子证实一下上面的说法:

文件demo.py:

文件demo1.py :

运行文件demo.py后,可以看到读取 f 的内容为:

可以看到读取的 f 中的结果就是demo1.py中调用 main 函数的返回值。

如果不用变量c来接收函数main的返回值,那么结果又是怎样的呢?

可以看到 f 的值为空。

综上所述,我认为此处我的 文件对象f 是因为调用函数find_parameters的位置没有定义变量接收返回值。

于是,我定义三个变量

c, g, r

用来接收调用 find_parameters函数 的返回值 best_c,best_g,best_rate。

再次打印输出文件对象f的值,如图所示:

f的内容为:b"hello!\r\n\xca\xe4\xc8\xeb\xb5\xc4\xb2\xce\xca\xfd\xca\xfd\xc1\xbf\xce\xaa\xa3\xba4\r\n\xb5\xda0\xb2\xce\xca\xfd\xce\xaa:.\\grid.py\r\n\xb5\xda1\xb2\xce\xca\xfd\xce\xaa:-svmtrain\r\n\xb5\xda2\xb2\xce\xca\xfd\xce\xaa:..\\windows\\svm-train.exe\r\n\xb5\xda3\xb2\xce\xca\xfd\xce\xaa:train.txt.scale\r\noptions\xb5\xc4\xc4\xda\xc8\xdd\xce\xaa\xa3\xba['-svmtrain', '..\\\\windows\\\\svm-train.exe']\r\n\xd5\xe2\xc0\xef\xca\xc7-svmtrain\r\n\xbe\xad\xb9\xfd\xb8\xc4\xb1\xe4\xba\xf3options\xce\xaa:<__main__.GridOption object at 0x000001C2F77CF700>\r\n[local] 5 -7 97.8675 (best c=32.0, g=0.0078125, rate=97.8675)\r\n[local] -1 -7 94.2999 (best c=32.0, g=0.0078125, rate=97.8675)\r\n[local] 5 -1 99.8659 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] -1 -1 99.088 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] 11 -7 99.2489 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] 11 -1 99.8391 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] 5 -13 94.2865 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] -1 -13 38.2779 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] 11 -13 97.6797 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] -3 -7 88.6937 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] -3 -1 97.1701 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] -3 -13 16.8991 (best c=32.0, g=0.5, rate=99.8659)\r\n[local] 5 1 99.8927 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] -1 1 99.6915 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 11 1 99.8927 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] -3 1 99.1148 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 9 -7 98.8734 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 9 -1 99.8391 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 9 -13 96.4726 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 9 1 99.8927 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 5 -11 95.3594 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] -1 -11 66.5504 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 11 -11 98.4979 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] -3 -11 38.2779 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 9 -11 97.6797 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 3 -7 96.4995 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 3 -1 99.8391 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 3 -13 88.7607 (best c=32.0, g=2.0, rate=99.8927)\r\n[local] 3 1 99.8927 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 -11 94.2865 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 5 -5 98.8332 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -1 -5 95.4131 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 11 -5 99.7452 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -3 -5 94.2731 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 9 -5 99.7318 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 -5 98.0955 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -7 99.6513 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -1 99.8391 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -13 98.7661 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 1 99.8927 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -11 98.7795 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -5 99.7452 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 5 -15 88.7607 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -1 -15 16.8991 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 11 -15 96.4726 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -3 -15 16.8991 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 9 -15 95.346 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 -15 66.5236 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -15 98.4844 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -7 66.3761 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -1 94.9034 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -13 16.8991 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 1 96.1239 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -11 16.8991 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -5 88.5864 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -15 16.8991 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 5 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -1 3 99.155 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 11 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -3 3 94.3804 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 9 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 3 69.3938 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -7 98.5783 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -1 99.8525 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -13 95.346 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 1 99.8927 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -11 96.4726 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -5 99.3026 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -15 94.2865 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 5 -9 96.4861 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -1 -9 88.7071 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 11 -9 98.7661 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -3 -9 66.6711 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 9 -9 98.5247 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 -9 95.346 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -9 99.155 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -9 38.2779 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -9 97.72 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -7 95.3326 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -1 99.6647 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -13 66.5236 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 1 99.8793 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -11 88.7473 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -5 96.6738 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -15 38.2779 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 3 99.4903 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -9 94.2865 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 5 -3 99.7183 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -1 -3 96.9957 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 11 -3 99.7988 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -3 -3 95.279 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 9 -3 99.8256 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 3 -3 99.316 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 15 -3 99.7988 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] -5 -3 94.2462 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 7 -3 99.8256 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 1 -3 98.5113 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -7 99.5842 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -1 99.8391 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -13 98.4576 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 1 99.8927 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -11 98.7661 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -5 99.7318 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -15 97.6797 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 3 99.5038 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -9 98.8734 (best c=8.0, g=2.0, rate=99.8927)\r\n[local] 13 -3 99.7988 (best c=8.0, g=2.0, rate=99.8927)\r\n8.0 2.0 99.8927\r\nc:3\r\ng:1\r\nr:99.8927\r\n"

可以看到f不再为空了,其实f中保存的值就是运行文件grid.py过程中的打印输出信息!

  • 33
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值