2014-01-29 118 views
1

我有使用Python的itertools庫的這個函數創建一個列表(實際上是一個迭代器):這種格式如何只選擇字符串/整數列表中的整數?

comb = [c for i in range(len(menu)+1) for c in combinations(menu, i)] 

爲了給你一個想法menu的列表[「食品名稱」,克糖]的:

menu = [ ["cheesecake", 13], ["pudding", 24], ["bread", 13], .........] 

所以comb本質上是包含了所有菜單子列表的可能組合的列表。我必須通過梳理創建所有可能的項目組合,其總糖含量將完全等於(不少,不會更多,正確)max_sugar = 120

所以我想我可以遍歷comb中的每個可能的組合,並檢查一個if陳述,如果這個組合中物品的糖的總和等於完全max_sugar。如果是這種情況,我想輸出這個組合中菜單項的名稱。否則,我想通過其他組合繼續以這種方式:

for e in comb: 
    for l in e: 
     if sum(sugars of items in this combination) == max_sugar: # pseudo-code 
      print items in this combination #pseudo code 

我想我遇到的問題是在l來訪問每個項目只有糖值和檢查條件,如果它是TRUE打印名。 我不擅長Python列表解析,但在過去的幾天裏我已經有了很多改進!

flag = 0 
num_comb = 1 
comb = [c for i in range(len(menu)+1) for c in combinations(menu, i)] 

for e in comb: 
    if sum(l[1] for l in e) == targetSugar: 
     print "The combination number " + str(num_comb) + " is:\n" 
     print([l[0] for l in e]) 
     print "\n\n\n" 
     num_comb += 1 
     flag = 1 

if flag == 0: 
    print "there are no combinations of dishes for your sugar intake... Sorry! :D " 

回答

0

每個項目的ecomb是列表的元組,如:

e == (['cheesecake', 13], ['bread', 13]) 

的項目因此,每個le是一個列表:

l == ['cheesecake', 13] 

對於本列表中,字符串cheesecakel[0],整數13l[1]。因此,你可能想:

for e in comb: 
    if sum(l[1] for l in e) == max_sugar: 
     print([l[0] for l in e]) 

由於wim曾建議,你也可以使用「解壓縮」爲你迭代,這使得代碼更清晰一點拆分每個列表到合理的名稱:

for e in comb: 
    if sum(sugar for name, sugar in e) == max_sugar: 
     print([name for name, sugar in e]) 

對於短期menu列表你給與max_sugar == 26,我得到:

['cheesecake', 'bread'] 

或者與max_sugar == 37

['cheesecake', 'pudding'] 
['pudding', 'bread'] 
+1

更清晰地使用拆包,即''爲名,糖在電子' – wim

+0

這是一個很好的觀點,謝謝;編輯 – jonrsharpe

+0

謝謝大家的幫忙!現在有很多意義! – user3245453

1

當你被影射,你可以用一個列表理解通過所有的菜單組合進行迭代,並限制那些meals與完全糖量你正在尋找:

>>> # input data 
>>> menu = [ ["cheesecake", 13], ["pudding", 24], ["bread", 13] ] 
>>> max_sugar = 26 
>>> # construct all combinations of menu items 
>>> comb = [c for i in range(1, len(menu)+1) for c in combinations(menu, i)] 
>>> list(comb) 
[(['cheesecake', 13],), (['pudding', 24],), (['bread', 13],), (['cheesecake', 13], ['pudding', 24]), (['cheesecake', 13], ['bread', 13]), (['pudding', 24], ['bread', 13]), (['cheesecake', 13], ['pudding', 24], ['bread', 13])] 
>>> # restrict to meals with exactly max_sugar 
>>> meals = [ e for e in comb if sum(sugar for _, sugar in e) == max_sugar ] 
>>> meals 
[(['cheesecake', 13], ['bread', 13])] 

唯一棘手的部分是當你迭代每個組合時,每個元素e是一個包含名稱和糖數的列表。因此,你可以使用測量糖量在組合e

sum(sugar for _, sugar in e) == max_sugar 

大廈關閉的這一點,如果你只是想返回每餐食物的名稱,你可以使用:

>>> [ [name for name, sugar in m] for m in meals ] 
[['cheesecake', 'bread']] 
+0

其實我想要檢查每個可能的餐點,如果該餐中所有物品的糖的總和等於'max_sugar'。我希望這更有意義。因爲我想輸出所有可能的食物(可以由1,2,3或...組成,只要它們的糖的總數等於'max_sugar'。因此,在創建所有可能的膳食組合後,我非常想過濾掉那些滿足我的條件的人,並嘗試僅輸出這些用餐中每個項目的名稱 – user3245453

+0

@ user3245453:我演示的代碼找到了所有具有max_sugar'的菜單項的組合。然後,您可以使用我答案末尾的代碼段輸出每個「用餐」的每個菜單項的名稱。 – mdml

相關問題