2014-01-29 55 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

相关问题