查找两组相同列表的所有唯一组合?

2024-05-28 09:37:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两组相同的列表和另一个列表,我试图找到所有唯一的组合。我很难想出如何在不重复同一行中的项目(例如:培根,培根)的情况下获得这些组合

我的名单:

crust = ['Thin Crust', 'Hand Tossed']
topping1 = ['Bacon', 'Pepperoni', 'Steak']
topping2 = ['Bacon', 'Pepperoni', 'Steak']
sauce1 = ['Tomato', 'BBQ', 'Ranch']
sauce2 = ['Tomato', 'BBQ', 'Ranch']

我正在尝试获取一个输出,该输出按以下顺序列出所有唯一的组合: 外壳|顶部1 |顶部2 |酱1 |酱2 例:

Thin Crust, Bacon, Pepperoni, Tomato, BBQ
Thin Crust, Bacon, Pepperoni, Tomato, Ranch
Thin Crust, Bacon, Pepperoni, BBQ, Ranch
....

尝试:

import itertools

crust = ['Thin Crust', 'Hand Tossed']
topping1 = ['Bacon', 'Pepperoni', 'Steak']
topping2 = ['Bacon', 'Pepperoni', 'Steak']
sauce1 = ['Tomato', 'BBQ', 'Ranch']
sauce2 = ['Tomato', 'BBQ', 'Ranch']

test = list(itertools.product(crust,topping1,topping2,sauce1,sauce2))
print(test)

我的第一个想法是使用itertools来攻击它,但我不知道如何防止像上面提到的那样在同一行中重复。你有什么想法吗


Tags: 列表thinitertoolsbaconbbqsteaktomatoranch
3条回答

可以使用递归生成器函数:

def combos(d, c = []):
  if not d:
     yield c
  else:
     for i in filter(lambda x:x not in c, d[0]):
        yield from combos(d[1:], c+[i])

print(list(combos([crust,topping1,topping2,sauce1,sauce2])))

输出:

[['Thin Crust', 'Bacon', 'Pepperoni', 'Tomato', 'BBQ'], ['Thin Crust', 'Bacon', 'Pepperoni', 'Tomato', 'Ranch'], ['Thin Crust', 'Bacon', 'Pepperoni', 'BBQ', 'Tomato'], ['Thin Crust', 'Bacon', 'Pepperoni', 'BBQ', 'Ranch'], ['Thin Crust', 'Bacon', 'Pepperoni', 'Ranch', 'Tomato'], ['Thin Crust', 'Bacon', 'Pepperoni', 'Ranch', 'BBQ'], ['Thin Crust', 'Bacon', 'Steak', 'Tomato', 'BBQ'], ['Thin Crust', 'Bacon', 'Steak', 'Tomato', 'Ranch'], ['Thin Crust', 'Bacon', 'Steak', 'BBQ', 'Tomato'], ['Thin Crust', 'Bacon', 'Steak', 'BBQ', 'Ranch'], ['Thin Crust', 'Bacon', 'Steak', 'Ranch', 'Tomato'], ['Thin Crust', 'Bacon', 'Steak', 'Ranch', 'BBQ'], ['Thin Crust', 'Pepperoni', 'Bacon', 'Tomato', 'BBQ'], ['Thin Crust', 'Pepperoni', 'Bacon', 'Tomato', 'Ranch'], ['Thin Crust', 'Pepperoni', 'Bacon', 'BBQ', 'Tomato'], ['Thin Crust', 'Pepperoni', 'Bacon', 'BBQ', 'Ranch'], ['Thin Crust', 'Pepperoni', 'Bacon', 'Ranch', 'Tomato'], ['Thin Crust', 'Pepperoni', 'Bacon', 'Ranch', 'BBQ'], ['Thin Crust', 'Pepperoni', 'Steak', 'Tomato', 'BBQ'], ['Thin Crust', 'Pepperoni', 'Steak', 'Tomato', 'Ranch'], ['Thin Crust', 'Pepperoni', 'Steak', 'BBQ', 'Tomato'], ['Thin Crust', 'Pepperoni', 'Steak', 'BBQ', 'Ranch'], ['Thin Crust', 'Pepperoni', 'Steak', 'Ranch', 'Tomato'], ['Thin Crust', 'Pepperoni', 'Steak', 'Ranch', 'BBQ'], ['Thin Crust', 'Steak', 'Bacon', 'Tomato', 'BBQ'], ['Thin Crust', 'Steak', 'Bacon', 'Tomato', 'Ranch'], ['Thin Crust', 'Steak', 'Bacon', 'BBQ', 'Tomato'], ['Thin Crust', 'Steak', 'Bacon', 'BBQ', 'Ranch'], ['Thin Crust', 'Steak', 'Bacon', 'Ranch', 'Tomato'], ['Thin Crust', 'Steak', 'Bacon', 'Ranch', 'BBQ'], ['Thin Crust', 'Steak', 'Pepperoni', 'Tomato', 'BBQ'], ['Thin Crust', 'Steak', 'Pepperoni', 'Tomato', 'Ranch'], ['Thin Crust', 'Steak', 'Pepperoni', 'BBQ', 'Tomato'], ['Thin Crust', 'Steak', 'Pepperoni', 'BBQ', 'Ranch'], ['Thin Crust', 'Steak', 'Pepperoni', 'Ranch', 'Tomato'], ['Thin Crust', 'Steak', 'Pepperoni', 'Ranch', 'BBQ'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'Tomato', 'BBQ'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'Tomato', 'Ranch'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'BBQ', 'Tomato'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'BBQ', 'Ranch'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'Ranch', 'Tomato'], ['Hand Tossed', 'Bacon', 'Pepperoni', 'Ranch', 'BBQ'], ['Hand Tossed', 'Bacon', 'Steak', 'Tomato', 'BBQ'], ['Hand Tossed', 'Bacon', 'Steak', 'Tomato', 'Ranch'], ['Hand Tossed', 'Bacon', 'Steak', 'BBQ', 'Tomato'], ['Hand Tossed', 'Bacon', 'Steak', 'BBQ', 'Ranch'], ['Hand Tossed', 'Bacon', 'Steak', 'Ranch', 'Tomato'], ['Hand Tossed', 'Bacon', 'Steak', 'Ranch', 'BBQ'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'Tomato', 'BBQ'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'Tomato', 'Ranch'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'BBQ', 'Tomato'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'BBQ', 'Ranch'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'Ranch', 'Tomato'], ['Hand Tossed', 'Pepperoni', 'Bacon', 'Ranch', 'BBQ'], ['Hand Tossed', 'Pepperoni', 'Steak', 'Tomato', 'BBQ'], ['Hand Tossed', 'Pepperoni', 'Steak', 'Tomato', 'Ranch'], ['Hand Tossed', 'Pepperoni', 'Steak', 'BBQ', 'Tomato'], ['Hand Tossed', 'Pepperoni', 'Steak', 'BBQ', 'Ranch'], ['Hand Tossed', 'Pepperoni', 'Steak', 'Ranch', 'Tomato'], ['Hand Tossed', 'Pepperoni', 'Steak', 'Ranch', 'BBQ'], ['Hand Tossed', 'Steak', 'Bacon', 'Tomato', 'BBQ'], ['Hand Tossed', 'Steak', 'Bacon', 'Tomato', 'Ranch'], ['Hand Tossed', 'Steak', 'Bacon', 'BBQ', 'Tomato'], ['Hand Tossed', 'Steak', 'Bacon', 'BBQ', 'Ranch'], ['Hand Tossed', 'Steak', 'Bacon', 'Ranch', 'Tomato'], ['Hand Tossed', 'Steak', 'Bacon', 'Ranch', 'BBQ'], ['Hand Tossed', 'Steak', 'Pepperoni', 'Tomato', 'BBQ'], ['Hand Tossed', 'Steak', 'Pepperoni', 'Tomato', 'Ranch'], ['Hand Tossed', 'Steak', 'Pepperoni', 'BBQ', 'Tomato'], ['Hand Tossed', 'Steak', 'Pepperoni', 'BBQ', 'Ranch'], ['Hand Tossed', 'Steak', 'Pepperoni', 'Ranch', 'Tomato'], ['Hand Tossed', 'Steak', 'Pepperoni', 'Ranch', 'BBQ']]

您还可以使用itertools.product预先生成所有组合,然后使用重复值筛选结果:

import itertools as it
r = [i for i in it.product(crust,topping1,topping2,sauce1,sauce2) if len(i) == len(set(i))]

如果我理解正确的话,你真正想要的是每两种配料和酱汁的组合,然后是他们的产品。如果是这样,您不需要相同的列表

from itertools import combinations, product

crust = ['Thin Crust', 'Hand Tossed']
topping = ['Bacon', 'Pepperoni', 'Steak']
sauce = ['Tomato', 'BBQ', 'Ranch']

topping_combs = combinations(topping, r=2)
sauce_combs = combinations(sauce, r=2)

# >> FOR DEMO
topping_combs = list(topping_combs)
sauce_combs = list(sauce_combs)
print(topping_combs)
print(sauce_combs)
print()
# << FOR DEMO

prod = product(crust, topping_combs, sauce_combs)
for c, t, s in prod:
    print(c, *t, *s, sep=', ')

输出:

[('Bacon', 'Pepperoni'), ('Bacon', 'Steak'), ('Pepperoni', 'Steak')]
[('Tomato', 'BBQ'), ('Tomato', 'Ranch'), ('BBQ', 'Ranch')]

Thin Crust, Bacon, Pepperoni, Tomato, BBQ
Thin Crust, Bacon, Pepperoni, Tomato, Ranch
Thin Crust, Bacon, Pepperoni, BBQ, Ranch
Thin Crust, Bacon, Steak, Tomato, BBQ
Thin Crust, Bacon, Steak, Tomato, Ranch
Thin Crust, Bacon, Steak, BBQ, Ranch
Thin Crust, Pepperoni, Steak, Tomato, BBQ
Thin Crust, Pepperoni, Steak, Tomato, Ranch
Thin Crust, Pepperoni, Steak, BBQ, Ranch
Hand Tossed, Bacon, Pepperoni, Tomato, BBQ
Hand Tossed, Bacon, Pepperoni, Tomato, Ranch
Hand Tossed, Bacon, Pepperoni, BBQ, Ranch
Hand Tossed, Bacon, Steak, Tomato, BBQ
Hand Tossed, Bacon, Steak, Tomato, Ranch
Hand Tossed, Bacon, Steak, BBQ, Ranch
Hand Tossed, Pepperoni, Steak, Tomato, BBQ
Hand Tossed, Pepperoni, Steak, Tomato, Ranch
Hand Tossed, Pepperoni, Steak, BBQ, Ranch

已经有使用itertools模块的解决方案,因此这里有一个从头构建的解决方案:

crust = ['Thin Crust', 'Hand Tossed']
topping1 = ['Bacon', 'Pepperoni', 'Steak']
topping2 = ['Bacon', 'Pepperoni', 'Steak']
sauce1 = ['Tomato', 'BBQ', 'Ranch']
sauce2 = ['Tomato', 'BBQ', 'Ranch']

def create_uniques(options, creation_so_far):
    # options is a list of lists
    # creation_so_far is a set of options we've picked
    uniques = set()
    def recurse(options, creation_so_far):
        if not options:
            # we've gone through every list of options we have
            # e.g. we've gone through
            # crust, topping1, topping2, sauce1, sauce2
            # so we add this to our set of uniques
            uniques.add(tuple(sorted(creation_so_far)))
            return
        current_option = options[0] # we pick the current option
        for choice in current_option:
            # make sure the choice we're adding isn't already in our creation_so_far
            if choice not in creation_so_far:
                creation_so_far.add(choice)
                recurse(options[1:], creation_so_far)
                creation_so_far.remove(choice)
    recurse(options, creation_so_far)
    return uniques

uniques = create_uniques([crust,topping1,topping2,sauce1,sauce2], set())

for unique in uniques:
    print(unique)
                                                                                 ```

相关问题 更多 >