【问题标题】:Too many values to unpack (expected 4)需要解压的值太多(预期为 4)
【发布时间】:2017-12-05 23:01:57
【问题描述】:

我有这段基本代码只是试图将文件拆分为 4 个列表。 .txt 文件的格式如代码下方所示,每个数字用空格分隔。出现的错误是“ValueError: too many values to unpack (expected 4)”。

file = open("myfreefall.txt","r")
for line in file:
     if not line.startswith('#'):
         v,a,t,y= line.split(' ')


#v  a  t  y
-0.10 -9.81 0.01 5500.00
-0.20 -9.81 0.02 5500.00
-0.29 -9.81 0.03 5500.00
-0.39 -9.81 0.04 5499.99
-0.49 -9.81 0.05 5499.99
-0.59 -9.81 0.06 5499.99
-0.69 -9.81 0.07 5499.98
-0.78 -9.81 0.08 5499.97
...

但是,我将代码更改为如下所示,以测试预期有多少变量,并且错误更改为“没有足够的值来解包(预期 5,得到 4)”。这没有意义,因为现在代码正在解压缩我想要的四个变量!任何解决方案/指针将不胜感激。

file = open("myfreefall.txt","r")
for line in file:
     if not line.startswith('#'):
         v,a,t,y,test= line.split(' ')

【问题讨论】:

  • 为什么不直接打印 line.split() 看看你得到了多少?
  • 它在哪条线上窒息?尝试打印该行以查看。
  • 您的文本文件的格式与您的想法不一致。
  • Catch the error 并检查/打印除套件中的相关数据-likeline。这应该让您了解正在发生的事情。

标签: python list line


【解决方案1】:

正如评论者所建议的,尝试打印该行以查看实际导致问题的行(但请确保在line.split 之前插入打印)。

最有可能的问题是末尾的空行,它被读取为换行符。如果是这样,最简单的解决方案可能是在 if 语句中添加另一个条件:

file = open("myfreefall.txt","r")
for line in file:
     if not line.startswith('#') and line != '\n':
     # or, more robust:
     if not line.startswith('#') and len(line) == 4:
         v,a,t,y= line.split(' ')

或者使用 try/except:

file = open("myfreefall.txt","r")
for line in file:
    try:
       v,a,t,y= line.split(' ')
    except ValueError:
       continue
       # Skip over this line if the extraction fails

第二个 if 语句更加健壮,因为它只会在恰好有四个列表条目要使用时才会尝试提取您的四个变量。任何其他情况(要提取的更多或更少条目)都将被忽略。您可以根据自己的需要对其进行更多调整,例如如果您还想允许读取更长的行,请将其更改为 'len(line) >= 4'。

老实说,我想不出 try/except 变体有什么特别的优势,但既然我只是把它写出来,我不妨把它留在里面。事实上,它可能有点太健壮了,因为它还会跳过导致 ValueErrors 的行,原因其他而不是条目太少。

您描述的第二次尝试失败是完全有道理的。 你告诉 python 将四个条目的列表拆分为五个变量,v、a、t、y 和 test。这就是错误所说的“预期为 5,得到 4”时所指的内容。您的错误行为可能会改变,因为代码现在失败得更快。在它适用于除最后一行之外的所有行之前,只有一个列表条目可供使用。随着您对五个变量的更改,它会导致第一行出现错误,其中有四个条目,但现在您要求五个。

【讨论】:

    【解决方案2】:

    第二个错误是正确的,因为您按照这一行解压缩了 5 个值:

    v,a,t,y,test = line.split(' ')
    #       ^^^^
    

    由于分割时的每一行将返回 4 个元素,因此第 5 个值不存在,因此出现错误。请注意,从长远来看,使用这种解包方式可能会出现问题,特别是对于许多元素。对分割线的长度进行显式检查可能值得研究。

    对于您的原始问题,请尝试使用 line.split(),因为它会自动拆分空格 - 即空格可能是制表符或空白 unicode 字符之一(请参阅:http://jkorpela.fi/chars/spaces.html)。

    或者,可以在行上使用正则表达式来简化文本的解析:

    import re
    
    regex = re.compile('([-+]?[0-9]*\.[0-9]+|[0-9]+)')  # regex for floating-point numbers
    matches = regex.findall(line)  # `matches` will return a list
    

    【讨论】:

      猜你喜欢
      • 2019-12-28
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 2019-01-13
      • 2012-09-27
      • 1970-01-01
      • 2021-10-20
      相关资源
      最近更新 更多