【问题标题】:too many values to unpack in a yield太多的值无法在产量中解压
【发布时间】:2013-04-25 00:27:57
【问题描述】:

这是一个 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)

【问题讨论】:

    标签: python runtime-error yield


    【解决方案1】:

    以下是建议

    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>
    

    参考

    【讨论】:

      【解决方案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):
      

      【讨论】:

        【解决方案3】:

        yield 在你的循环中一次两个项目,所以你必须一次捕获两个:

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

        【讨论】:

        • 我不明白产量?是不是像个回报? for pset1... 有什么作用?
        • @user1347096:阅读此问题的答案:stackoverflow.com/questions/231767/…
        • 这是一条红鲱鱼。问题不是一次两个与一次一个,而是一次尝试解压缩整个迭代器(充满对,但这没关系)。
        猜你喜欢
        • 2020-01-20
        • 1970-01-01
        • 2015-12-20
        • 2016-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多