如何创建所有唯一组合的列表,同时为每个组合保留一个合计列



我正在努力寻找所有可能的独特组合来制作三明治。我也想知道每个三明治要多少钱。我有三套两份清单,一份是该项目的清单,另一份是项目的价格清单。

bread = ['italian', 'wheat', 'honey oat']
bprice = [1, 2, 3]
meat = ['roastbeef', 'ham', 'turkey', 'steak']
mprice = [3, 1, 2, 4]
vegetable = ['lettuce', 'onions', 'tomatoes', 'pickles']
vprice = [1, 4, 2, 3]

我试图找到所有可能的唯一组合,但我也想要每个组合的总数。组合应该包含一个面包、一块肉和两种不同的蔬菜。例如:

输出:

Combinations                Total
italian, ham, onions, pickles           9
italian, turkey, onions, pickles       ...
wheat, ham, onions, pickles            ...

我完全不知道该怎么做。我研究了itertools.product,但这似乎只是得到了组合,而不是总数。我也想过索引来获得物品的价格,但同样不知道如何将其与组合列表以及词典相结合,但也不确定如何将其纳入所有组合的列表。有没有想过我该怎么做?

我想你可以这样做:

import pandas as pd #To display the results
from itertools import combinations, product
# Create bread dictionary 
bread = ['italian', 'wheat', 'honey oat']
bprice = [1, 2, 3]
breaddict = dict(zip(bread, bprice))
# Create meat dictionary
meat = ['roastbeef', 'ham', 'turkey', 'steak']
mprice = [3, 1, 2, 4]
meatdict= dict(zip(meat,mprice))
# Create veggie dictionary
vegetable = ['lettuce', 'onions', 'tomatoes', 'pickles']
vprice = [1, 4, 2, 3]
vegdict=dict(zip(vegetable, vprice))
# The real work is done here
# Create combinations of two veggies
# Then use that combination with bread and meat to calculate a product of sandwiches
sandwiches = product(bread,meat,combinations(vegetable,2))
# Create empty dataframe for storage and display
df=pd.DataFrame()
# Iterate through sandwiches 
# and use unpacking tuple and map with dictionary to populate dataframe
for b, m, v in sandwiches:
df=df.append(pd.concat([pd.Series(', '.join([b, m, *v])).rename('Combinations'),
pd.Series(sum([breaddict[b], 
meatdict[m], 
*map(vegdict.get, v)])).rename('Total')], 
axis=1))
print(df)

输出:

Combinations  Total
0     italian, roastbeef, lettuce, onions      9
1   italian, roastbeef, lettuce, tomatoes      7
2    italian, roastbeef, lettuce, pickles      8
3    italian, roastbeef, onions, tomatoes     10
4     italian, roastbeef, onions, pickles     11
..                                    ...    ...
67    honey oat, steak, lettuce, tomatoes     10
68     honey oat, steak, lettuce, pickles     11
69     honey oat, steak, onions, tomatoes     13
70      honey oat, steak, onions, pickles     14
71    honey oat, steak, tomatoes, pickles     12
[72 rows x 2 columns]

没有panda,但仍使用itertools.combinations和itertool.production

from itertools import combinations, product
bread = ['italian', 'wheat', 'honey oat']
bprice = [1, 2, 3]
breaddict = dict(zip(bread, bprice))
# Create meat dictionary
meat = ['roastbeef', 'ham', 'turkey', 'steak']
mprice = [3, 1, 2, 4]
meatdict= dict(zip(meat,mprice))
# Create veggie dictionary
vegetable = ['lettuce', 'onions', 'tomatoes', 'pickles']
vprice = [1, 4, 2, 3]
vegdict=dict(zip(vegetable, vprice))
# The real work is done here
# Create combinations of two veggies
# Then use that combination with bread and meat to calculate a product of sandwiches
sandwiches = product(bread,meat,combinations(vegetable,2))
sandwiches_with_price = [[b,m,*v], 
sum([breaddict[b], meatdict[m], *map(vegdict.get, v)])) for b, m, v in sandwiches]
sandwiches_with_price

输出:

[(['italian', 'roastbeef', 'lettuce', 'onions'], 9),
(['italian', 'roastbeef', 'lettuce', 'tomatoes'], 7),
(['italian', 'roastbeef', 'lettuce', 'pickles'], 8),
(['italian', 'roastbeef', 'onions', 'tomatoes'], 10),
(['italian', 'roastbeef', 'onions', 'pickles'], 11),
(['italian', 'roastbeef', 'tomatoes', 'pickles'], 9),
(['italian', 'ham', 'lettuce', 'onions'], 7),
(['italian', 'ham', 'lettuce', 'tomatoes'], 5),
(['italian', 'ham', 'lettuce', 'pickles'], 6),
(['italian', 'ham', 'onions', 'tomatoes'], 8),
(['italian', 'ham', 'onions', 'pickles'], 9),
(['italian', 'ham', 'tomatoes', 'pickles'], 7),
(['italian', 'turkey', 'lettuce', 'onions'], 8),
(['italian', 'turkey', 'lettuce', 'tomatoes'], 6),
(['italian', 'turkey', 'lettuce', 'pickles'], 7),
(['italian', 'turkey', 'onions', 'tomatoes'], 9),
(['italian', 'turkey', 'onions', 'pickles'], 10),
(['italian', 'turkey', 'tomatoes', 'pickles'], 8),
(['italian', 'steak', 'lettuce', 'onions'], 10),
(['italian', 'steak', 'lettuce', 'tomatoes'], 8),
(['italian', 'steak', 'lettuce', 'pickles'], 9),
(['italian', 'steak', 'onions', 'tomatoes'], 11),
(['italian', 'steak', 'onions', 'pickles'], 12),
(['italian', 'steak', 'tomatoes', 'pickles'], 10),
(['wheat', 'roastbeef', 'lettuce', 'onions'], 10),
(['wheat', 'roastbeef', 'lettuce', 'tomatoes'], 8),
(['wheat', 'roastbeef', 'lettuce', 'pickles'], 9),
(['wheat', 'roastbeef', 'onions', 'tomatoes'], 11),
(['wheat', 'roastbeef', 'onions', 'pickles'], 12),
(['wheat', 'roastbeef', 'tomatoes', 'pickles'], 10),
(['wheat', 'ham', 'lettuce', 'onions'], 8),
(['wheat', 'ham', 'lettuce', 'tomatoes'], 6),
(['wheat', 'ham', 'lettuce', 'pickles'], 7),
(['wheat', 'ham', 'onions', 'tomatoes'], 9),
(['wheat', 'ham', 'onions', 'pickles'], 10),
(['wheat', 'ham', 'tomatoes', 'pickles'], 8),
(['wheat', 'turkey', 'lettuce', 'onions'], 9),
(['wheat', 'turkey', 'lettuce', 'tomatoes'], 7),
(['wheat', 'turkey', 'lettuce', 'pickles'], 8),
(['wheat', 'turkey', 'onions', 'tomatoes'], 10),
(['wheat', 'turkey', 'onions', 'pickles'], 11),
(['wheat', 'turkey', 'tomatoes', 'pickles'], 9),
(['wheat', 'steak', 'lettuce', 'onions'], 11),
(['wheat', 'steak', 'lettuce', 'tomatoes'], 9),
(['wheat', 'steak', 'lettuce', 'pickles'], 10),
(['wheat', 'steak', 'onions', 'tomatoes'], 12),
(['wheat', 'steak', 'onions', 'pickles'], 13),
(['wheat', 'steak', 'tomatoes', 'pickles'], 11),
(['honey oat', 'roastbeef', 'lettuce', 'onions'], 11),
(['honey oat', 'roastbeef', 'lettuce', 'tomatoes'], 9),
(['honey oat', 'roastbeef', 'lettuce', 'pickles'], 10),
(['honey oat', 'roastbeef', 'onions', 'tomatoes'], 12),
(['honey oat', 'roastbeef', 'onions', 'pickles'], 13),
(['honey oat', 'roastbeef', 'tomatoes', 'pickles'], 11),
(['honey oat', 'ham', 'lettuce', 'onions'], 9),
(['honey oat', 'ham', 'lettuce', 'tomatoes'], 7),
(['honey oat', 'ham', 'lettuce', 'pickles'], 8),
(['honey oat', 'ham', 'onions', 'tomatoes'], 10),
(['honey oat', 'ham', 'onions', 'pickles'], 11),
(['honey oat', 'ham', 'tomatoes', 'pickles'], 9),
(['honey oat', 'turkey', 'lettuce', 'onions'], 10),
(['honey oat', 'turkey', 'lettuce', 'tomatoes'], 8),
(['honey oat', 'turkey', 'lettuce', 'pickles'], 9),
(['honey oat', 'turkey', 'onions', 'tomatoes'], 11),
(['honey oat', 'turkey', 'onions', 'pickles'], 12),
(['honey oat', 'turkey', 'tomatoes', 'pickles'], 10),
(['honey oat', 'steak', 'lettuce', 'onions'], 12),
(['honey oat', 'steak', 'lettuce', 'tomatoes'], 10),
(['honey oat', 'steak', 'lettuce', 'pickles'], 11),
(['honey oat', 'steak', 'onions', 'tomatoes'], 13),
(['honey oat', 'steak', 'onions', 'pickles'], 14),
(['honey oat', 'steak', 'tomatoes', 'pickles'], 12)]

我假设你每个三明治有2种蔬菜、1种肉和1种面包。

bread = ['italian', 'wheat', 'honey oat']
bprice = [1, 2, 3]
meat = ['roastbeef', 'ham', 'turkey', 'steak']
mprice = [3, 1, 2, 4]
vegetable = ['lettuce', 'onions', 'tomatoes', 'pickles']
vprice = [1, 4, 2, 3]
# prices are easier to manage in a dict, let's do that.
prices = {x:y for x,y in zip(bread, bprice)}
prices.update({x:y for x,y in zip(meat, mprice)})
prices.update({x:y for x,y in zip(vegetable, vprice)})

#now let's make all the vegetable combinations:
combveg = [ sorted((x ,y)) for x in vegetable for y in vegetable if len(set([x,y])) == 2 ]
# remove duplicates
combveg = list(set([tuple(x) for x in combveg]))
# now calculate all the sandwich possibilities
sandwiches = [[b, m] + list(vgs) for b in bread for m in meat for vgs in combveg]
# just have to build their prices now
sandwiches_with_price = [(sandwich, sum([prices[item] for item in sandwich])) for sandwich in sandwiches]

大多数列表操作都可以链接,或者使用一些生成器表达式进行优化,但目的是解释每个步骤。

另一个纯Python解决方案。

from operator import itemgetter
from itertools import product, combinations
bread = ['italian', 'wheat', 'honey oat']
bprice = [1, 2, 3]
meat = ['roastbeef', 'ham', 'turkey', 'steak']
mprice = [3, 1, 2, 4]
vegetable = ['lettuce', 'onions', 'tomatoes', 'pickles']
vprice = [1, 4, 2, 3]
d = dict()
d.update(zip(bread, bprice))
d.update(zip(meat, mprice))
d.update(zip(vegetable, vprice))
for p in product(bread, meat, combinations(vegetable, 2)):
# make 1 tuple from list and tuple (from combinations)
p = p[0:2] + p[2]
print('{:<40} = {}'.format(', '.join(p), sum(itemgetter(*p)(d))))

它使用物品的产品(Scott Boston使用(

此外,它还有一个字典切片:

itemgetter(*p)(d))

这从字典中获取(面包、肉、蔬菜产品p(的价格

以下代码行:

p = p[0:2] + p[2]

这很难,但我不知道如何将combinations(vegetable, 2)生成的元组转换为单个项,而不是它生成的元组。

打印:

italian, roastbeef, lettuce, onions      = 9
italian, roastbeef, lettuce, tomatoes    = 7
italian, roastbeef, lettuce, pickles     = 8
italian, roastbeef, onions, tomatoes     = 10
italian, roastbeef, onions, pickles      = 11
italian, roastbeef, tomatoes, pickles    = 9
italian, ham, lettuce, onions            = 7
. . .
honey oat, steak, lettuce, tomatoes      = 10
honey oat, steak, lettuce, pickles       = 11
honey oat, steak, onions, tomatoes       = 13
honey oat, steak, onions, pickles        = 14
honey oat, steak, tomatoes, pickles      = 12

最新更新