Too many values to unpack (expected 4)

不打扰是莪最后的温柔 提交于 2020-01-06 08:51:08

问题


I have this piece of basic code just trying to split a file into 4 lists. The .txt file is formatted as shown underneath the code, with spaces delimiting each number. The error appearing is '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
...

However I changed the code to be as shown below to test how many variables it was expecting, and the error changed to 'not enough values to unpack (expected 5, got 4)'. This doesn't make sense as now the code is unpacking the four variables I wanted! Any solutions/pointers would be much appreciated.

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

回答1:


As commenters have suggested, try printing the line to see the line that's actually causing a problem (but be sure to insert the print before the line.split).

The most likely problem is a blank line at the end, which is read as a newline character. If so the easiest solution is probably to tack on another condition to the if statement:

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(' ')

Or with a 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

The second if-statement is more robust because it will only try to extract your four variables if there are exactly four list entries to work with. Any other case (more or fewer entries to extract from) will be ignored. You can tailor it a bit more to your needs, e.g. by changing it to 'len(line) >= 4' if you wanted to allow longer lines to be read as well.

To be honest, I can't think of a particular advantage for the try/except variant, but since I just wrote it out I might as well leave it in. It might be a bit too robust, in fact, because it would also skip lines that cause ValueErrors for reasons other than there being too few entries to work with.

Your second attempt failing as you describe makes perfect sense. You're telling python to split a list of four entries into five variables, v, a, t, y and test. That's what the error is referring to when it says, 'expected 5, got 4'. The behaviour of your error probably changed because the code fails a lot sooner now. Before it was working for all lines except the last one, where there's only one list entry to use. With your change to five variables it's causing an error with the very first line, where there are four entries but now you're asking for five.




回答2:


The second error is correct since you're unpacking 5 values as per this line:

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

Since each line when split will return 4 elements, a 5th value is non-existent, hence the error. Note that using unpacking this way can be problematic in the long run, particularly with many elements. It may be worth examining doing an explicit check on the length of the split line.

For your original problem, try using line.split() since this automatically splits on whitespace - i.e. it's possible that the space may be a tab, or one of the blank unicode characters (see: http://jkorpela.fi/chars/spaces.html).

Or, one could use a regex on the line which could simplify parsing the text:

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


来源:https://stackoverflow.com/questions/47664102/too-many-values-to-unpack-expected-4

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!