2013-05-01 4 views
1

Это упражнение, когда Item является классом, и когда я запускаю testAll, у меня есть значениеError. Выход предполагают, чтобы вернуть только два значения, содержание 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) 

ответ

2

Вы yield две вещи в то время в вашем цикле, так что вы должны поймать две одновременно:

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

Я не понимаю доходность? это не похоже на возвращение? Что делает для pset1 ... делать? – user1347096

+0

@ user1347096: Читайте ответы на этот вопрос: http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained – Blender

+0

Это красная селедка. Проблема не в двух случаях по сравнению с одной за раз, она пытается распаковать весь итератор (полный пар, но это не имеет значения) сразу. – abarnert

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): 
Смежные вопросы