太多的值要在收益率中解包

时间:2013-05-01 00:01:11

标签: python runtime-error yield

这是一个练习,其中Item是一个类,当我运行testAll时,我有一个valueError。产量假设只返回2个值,即2个包的内容:

> Traceback (most recent call last):
  File "<pyshell#63>", line 1, in <module>
    testAll()
  File "/Downloads/L18_code.py", line 101, in testAll
    pset1,pset2=yieldAllCombos(items)
ValueError: too many values to unpack

def buildItems():
return [Item(n,v,w) for n,v,w in (('clock', 175, 10),
                                  ('painting', 90, 9),
                                  ('radio', 20, 4),
                                  ('vase', 50, 2),
                                  ('book', 10, 1),
                                  ('computer', 200, 20))]
def yieldAllCombos(items):
"""
Generates all combinations of N items into two bags, whereby each item is in one or
zero bags.

Yields a tuple, (bag1, bag2), where each bag is represented as a list of which item(s)
are in each bag.
"""
N = len(items)
# enumerate the 3**N possible combinations
for i in xrange(3**N):
    combo1 = []
    combo2 = []
    for j in xrange(N):
        # test bit jth of integer i
        if (i >> j) % 3 == 1:
            combo1.append(items[j])
        elif (i>>j) % 3 == 2:
            combo2.append(items[j])        
    yield(combo1,combo2)
def testAll():
    items = buildItems()
    pset1,pset2=yieldAllCombos(items)

3 个答案:

答案 0 :(得分:2)

你在循环中一次yield两项,所以你必须一次抓两个:

for pset1, pset2 in yieldAllCombos(items):
    ...

答案 1 :(得分:2)

如果您根本不理解生成器和yield语句,请参阅the Python Wiki page以获取一般概述。

问题在于您尝试将整个生成器yieldAllCombos(items)分配给两个变量。这仅在yieldAllCombos生成两个值时才有效,只需调用yield两次。

但这不是yieldAllCombos生成的。如果你想看看它做了什么,试试这个:

print(list(yieldAllCombos(items)))

你会看到你得到了一个大的2元组列表,每次在循环中调用yield时都会有一个元组。这不应该太令人惊讶,因为一个名为yieldAllCombos的函数应该给你很多组合,对吧?如果你想要解压缩整个东西,你必须将它解压缩到列表中每个2元组的一个变量中,而不仅仅是两个变量。但那可能不是你想要的。

你可能想要做的是对所有2元组进行迭代,然后解压缩每个元组。所以:

for pset1, pset2 in yieldAllCombos(items):

答案 2 :(得分:0)

以下是建议

def testAll():
    items = buildItems()
    gen=yieldAllCombos(items)
    for l in range(3**len(items)+0):
        pset = next(gen)
        pset1 = pset[0]
        pset2 = pset[1]
        print(str(len(pset1)) + '   ' + str(len(pset2)))
        for j in range(len(pset1)):
            print(str(pset1[j]))
        for k in range(len(pset2)):
            print(str(pset2[k]))

上面的代码会产生类似下面的输出

Pset 1 length : 4 Pset 2 length : 2
******** pset 1 ********
<painting, 90.0, 9.0>
<vase, 50.0, 2.0>
<book, 10.0, 1.0>
<computer, 200.0, 20.0>
******** pset 2 ********
<clock, 175.0, 10.0>
<radio, 20.0, 4.0>

参考