为什么在尝试将输入的一行分割并赋值给多个变量时会出现 ValueError 错误?

5
我尝试了一些类似这样的代码,从文件中读取问题和答案对:
questions_list = []
answers_list = []

with open('qanda.txt', 'r') as questions_file:
    for line in questions_file:
        line = line.strip()
        questions, answers = line.split(':')
        questions_list.append(questions)
        answers_list.append(answers)

但有时候我会从questions, answers = line.split(':')这行代码中得到一个异常,它会显示:
(Python 2.x) builtins.ValueError: 需要多于1个值来解包 (Python 3.x) ValueError: 解包的值不足(期望2个,实际只有1个) 或者,相反的问题: ValueError: 解包的值过多(期望2个) 为什么会出现这种情况?我该如何修复或解决这个问题?
4个回答

8

这可能是因为在进行分割时,没有:,所以该函数只返回一个参数,而不是两个。这可能是由于最后一行引起的,意味着你的最后一行除了空格之外什么都没有。就像这样:

>>> a = '   '
>>> a = a.strip()
>>> a
''
>>> a.split(':')
['']

.split返回的列表只包含一个空字符串。这是一个示例文件以便演示:

a: b
c: d
e: f

g: h
我们尝试使用以下脚本(val.txt 是上述文件的名称):
with open('val.txt', 'r') as v:
    for line in v:
        a, b = line.split(':')
        print a, b

这为我们带来了:

Traceback (most recent call last):
a  b

c  d
  File "C:/Nafiul Stuff/Python/testingZone/28_11_13/val.py", line 3, in <module>

    a, b = line.split(':')
e  f
ValueError: need more than 1 value to unpack

当尝试通过调试器查看时,变量line成为\n,这样就无法分割它。
然而,一个简单的逻辑修正可以解决这个问题:
with open('val.txt', 'r') as v:
    for line in v:
        if ':' in line:
            a, b = line.strip().split(':')
            print a, b

感谢回复。我文件中的第一行如下:“显示可用内存的命令是什么:free”。我很快会尝试上面的代码,看看会发生什么,谢谢。 - user3046660
如果这个答案对您有帮助,请随意点赞,如果它回答了您的问题,请点击问题左侧的勾选标记接受它。 - Games Brainiac

4

尝试:

question, answers = line.split(':', maxsplit=1)
question, __, answers = line.partition(':')

在Python 3中,您还可以做其他的事情:
question, *many_answers = line.split(':')

看起来像这样:

temp = line.split(':')
question = temp[0]
many_answers = tuple(temp[1:])

.partition 这个建议不错,但是给 .split 方法提供 maxsplit 参数只能解决输入中有太多项的情况,而不能解决太少的情况。 - Karl Knechtel

3
line.split(':') 明显返回一个只含有一个元素的列表而非两个元素。
因此无法将结果解包到questionsanswers中。例如:
>>> line = 'this-line-does-not-contain-a-colon'
>>> question, answers = line.split(':')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack

0
这种情况发生的原因可能有几个,正如其他答案中已经涵盖的那样。空行,或者只有问题而没有冒号的行。如果你想解析这些行即使它们没有冒号(例如,如果某些行只有问题),你可以将拆分方式更改为以下内容:
questions, answers, garbage = (line+'::').split(':', maxsplit=2)

这样,如果有的话,questionsanswers的值将被填充,如果原始文件中没有它们,则为空。就所有目的而言,请忽略变量garbage

将列表在拆分调用之后“填充”额外元素会更加优雅;这样就没有需要丢弃的“垃圾”。通过填充然后切片,maxsplit 参数变得不再必要。 - Karl Knechtel
@KarlKnechtel你的评论毫无意义。我添加了填充以便我们可以无误地进行分割。如果我们已经进行了分割,那么为什么还要进行填充呢?此外,如果在分割之前不进行填充,你会得到OP所遇到并且不想要的错误;填充的目的正是为了能够无误地进行分割。 - msb
很简单:不限制地分割,用空元素填充列表,将其切片到适当的长度,然后解包。 - Karl Knechtel
在我看来,这个方法更加冗长和复杂。我不同意它会更加优雅,对我来说恰恰相反。;) 但这是一个不同的解决方案,所以请随意发表你自己的答案。^_^ - msb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接