Python 2.6.6中的ValueError:需要超过2个值才能解包

17
我遇到了错误:ValueError: need more than 2 values to unpack,当我运行单元测试时,现在有两个失败和一个跳过。根据我所阅读的内容,源代码中第142行的方法为:
lambda i: get_error_count(self._error_lookup, i))
其中以下一行代码:
for test, err, capt in errors:
使用了以下这一行代码:
count = get_error_count(i)
引用说明Python 3.0中有类似这样的东西。多余的值可以绑定(作为列表)到最后一个变量上:
a,b,*c = [1,2,3,4,5]
将导致c包含[3,4,5]。
在Python 2.x中,您不能直接这样做,但应该能够创建一个函数来将输入参数元组长度延长或缩短到正确的长度,以便您可以执行以下操作:
a,c,b = fix(1,2)
d,e,f = fix(1,2,3,4)
然而,函数不会知道左侧序列的长度,因此必须将其作为额外的参数或硬编码传递进去。
因此,以下行:
count = get_error_count(i)
仅使用了一个变量,而
def get_error_count(lookup, index):
则需要2个变量。我应该使用什么作为第二个变量?来修复这个问题?
谢谢, -Kamal.
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/Current/bin/nosetests", line 10, in <module>
    sys.exit(run_exit())
  File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 117, in __init__
    **extra_args)
  File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/unittest.py", line 817, in __init__
    self.runTests()
  File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 196, in runTests
    result = self.testRunner.run(self.test)
  File "/Library/Frameworks/Python.framework/Versions/6.3/lib/python2.6/site-packages/nose/core.py", line 63, in run
    result.printErrors()
  File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 136, in printErrors
    lambda i: get_error_count(self._error_lookup, i))
  File "/NOSE_TRIM/nosetrim-read-only/nosetrim/nosetrim.py", line 142, in printErrorList
    for test, err, capt in errors:
ValueError: need more than 2 values to unpack

/

--------------------- >> 结束标准输出 << ----------------------


在1.263秒内运行了3个测试

4个回答

20

不需要在赋值语句中展开(unpack):

a, b, c = do_something()

尝试将结果赋值给单个变量并测试其长度:

t = do_something()
# t is now a tuple (or list, or whatever was returned) of results
if len(t) > 2:
    # Can use the third result!
    c = t[2]

2

errors是一个包含2到3个元素的元组列表。你想要在for循环中解压长度不同的元组。如你所述,在Python2中没有简单的方法来实现这一点。与其想出一个聪明的办法来实现这种行为,我建议确保errors列表始终包含长度为3的元组。这可以在每次向errors添加项目时完成,或者事后像这样完成:

errors = [(x[0], x[1], x[2]) if len(x) == 3 else (x[0], x[1], None) for x in errors]

或者你可以制作一个生成器(这与我的建议不符,不要找到聪明的方法来实现此行为):

def widen_tuples(iter, width, default=None):
    for item in iter:
        if len(item) < width:
            item = list(item)
            while len(item) < width:
                item.append(default)
            item = tuple(item)
        yield item

像这样使用:

>>> errors = [(1, 2), (1, 2, 3)] 
>>> for a, b, c in widen_tuples(errors, 3):
...     print a, b, c
1 2 None
1 2 3

1
我建议使用None元素将列表补全到所需的长度:
data = give_me_list()
(val1, val2, val3) = data + (3 - len(data)) * [None]

3 是左侧数值的数量。如果列表可能具有过多元素,则应对此进行保护:

data = give_me_list()[:3]
(val1, val2, val3) = data + (3 - len(data)) * [None]

1
你可以编写一个实用函数使你的结果统一:
def do_something2():
    return 1, 2

def do_something3():
    return 1, 2, 3

def do_something5():
    return 1, 2, 3, 4, 5

def uniform_result(*args):
    return args[0], args[1], args[2:]

a, b, c =  uniform_result(*do_something2())
print a, b, c
# 1 2 ()

a, b, c =  uniform_result(*do_something3())
print a, b, c
# 1 2 (3,)

a, b, c =  uniform_result(*do_something5())
print a, b, c
# 1 2 (3, 4, 5)

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