【问题标题】:itertools all possible combinations with multiple elementsitertools 与多个元素的所有可能组合
【发布时间】:2018-08-30 16:02:54
【问题描述】:

我正在尝试找到一种方法来使用以下类别生成所有可能的组合。我需要每个Type, Cutlery, IsWeekend 中的一个元素,以及FoodTypes 中的至少一个元素。在这些参数中,我想生成所有可能的选择组合。

options = {
'Type' : ['Breakfast', 'Brunch', 'Lunch', 'Dinner'],
'Cutlery': ['Knife', 'Fork'],
'IsWeekend' : ['True', 'False'],
'FoodTypes' : ['Sausage', 'Bacon', 'Eggs', 'Toast']
}

例如。

Breakfast, Knife, True, Sausage
Breakfast, Knife, True, Sausage, Bacon
....
Breakfast, Fork, False, Sasuage, Eggs, Toast

我一直在使用productcombinations 玩弄itertools,但我似乎找不到正确的食谱。它目前正在生成一个产品列表,但只使用每个列表中的一个元素,例如:

Breakfast, Knife, True, Sausage
Breakfast, Knife, True, Bacon

如何扩展它以涵盖多种食物选择?

【问题讨论】:

  • 您还没有明确说明您想要从无数种可能性中选择哪种组合。您的示例显示前三个列表中的每个列表中的一个项目,但最后一个列表的未指定组合(排列?)。请注意您的术语,因为您的示例对于您使用的术语来说似乎很不完整。
  • 是的,我很抱歉使用了一些含糊不清的术语,但我发现很难清楚地表达我想要达到的目标。

标签: python permutation itertools


【解决方案1】:

从您的示例中,您似乎想要食物的幂集,然后是其他条目的一个元素与该集的所有组合。我包含了 Python itertools 文档中给出的 powerset

from itertools import *

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

options = {
    'Type' : ['Breakfast', 'Brunch', 'Lunch', 'Dinner'],
    'Cutlery': ['Knife', 'Fork'],
    'IsWeekend' : ['True', 'False'],
    'FoodTypes' : ['Sausage', 'Bacon', 'Eggs', 'Toast']
}

menu = powerset(options['FoodTypes'])

for setting in product(
    options['Type'],
    options['Cutlery'],
    options['IsWeekend'],
    menu ):

    print(setting)

输出如下;我相信您可以展平列表并删除空菜单项(即留给读者作为练习)。

('Breakfast', 'Knife', 'True', ())
('Breakfast', 'Knife', 'True', ('Sausage',))
('Breakfast', 'Knife', 'True', ('Bacon',))
('Breakfast', 'Knife', 'True', ('Eggs',))
('Breakfast', 'Knife', 'True', ('Toast',))
('Breakfast', 'Knife', 'True', ('Sausage', 'Bacon'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Eggs'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Toast'))
('Breakfast', 'Knife', 'True', ('Bacon', 'Eggs'))
('Breakfast', 'Knife', 'True', ('Bacon', 'Toast'))
('Breakfast', 'Knife', 'True', ('Eggs', 'Toast'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Bacon', 'Eggs'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Bacon', 'Toast'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Eggs', 'Toast'))
('Breakfast', 'Knife', 'True', ('Bacon', 'Eggs', 'Toast'))
('Breakfast', 'Knife', 'True', ('Sausage', 'Bacon', 'Eggs', 'Toast'))
('Breakfast', 'Knife', 'False', ())
('Breakfast', 'Knife', 'False', ('Sausage',))
('Breakfast', 'Knife', 'False', ('Bacon',))
('Breakfast', 'Knife', 'False', ('Eggs',))
('Breakfast', 'Knife', 'False', ('Toast',))
...
('Dinner', 'Fork', 'False', ('Sausage', 'Eggs', 'Toast'))
('Dinner', 'Fork', 'False', ('Bacon', 'Eggs', 'Toast'))
('Dinner', 'Fork', 'False', ('Sausage', 'Bacon', 'Eggs', 'Toast'))

【讨论】:

  • 是的,这正是我要找的。谢谢!
【解决方案2】:

您可以使用itertools.combinations 来执行此操作,如下所示:

from itertools import combinations

options = {
    'Type':       ['Breakfast', 'Brunch', 'Lunch', 'Dinner'],
    'Cutlery':    ['Knife', 'Fork'],
    'IsWeekend' : ['True', 'False'],
    'FoodTypes' : ['Sausage', 'Bacon', 'Eggs', 'Toast']
}

# get a list of all the dictionary's values
lst = [j for i in options.values() for j in i]

for i in range(len(lst)+1):
    for s in combinations(lst, i): print(s)

注意:此解决方案计算字典值的扁平列表的所有 2^12 组合,并假设字典的值中不包含重复项。如果有重复项,在进入 for 循环之前,您可以轻松删除它们,例如使用sets

【讨论】:

  • 这将打印所有 2^12 个组合的扁平项目列表。我怀疑(但不确定)这是 OP 想要的。
  • @Prune 是的,我知道,如果我从 OP 的描述中理解得很好,我认为这就是 OP 想要的(我可能错了
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2023-03-02
相关资源
最近更新 更多