目前,我有一些人可以购买的物品清单,如下所示:
my_list = [
('Candy', 1.0, 20.5),
('Soda', 3.0, 10.25),
('Coffee', 1.2, 20.335),
('Soap', 1.2, 11.5),
('Spoon', 0.2, 2.32),
('Toast', 3.2, 12.335),
('Toothpaste', 3, 20.5),
('Creamer', .1, 5.5),
('Sugar', 2.2, 5.2),
]
每个项目都是这样设置的:
('Item Name', ItemCost, ItemValue)
我有一个列表拉出了前5名ItemValue
的项目。
print nlargest(5, my_list, key=itemgetter(2))
>>> [
('Candy', 1.0, 20.5),
('Toothpaste', 3, 20.5),
('Coffee', 1.2, 20.335),
('Toast', 3.2, 12.335),
('Soap', 1.2, 11.5),
]
我正在尝试检索结果,得出前5名ItemValue
中前5名ItemCost
等于或小于6。
有什么建议吗?
答案 0 :(得分:6)
您可以先进行过滤,然后在过滤后的列表中使用以下所有nlargest
。
f = [(a,b,c) for (a,b,c) in my_list if b <= 6]
但是对于这样的数据操作,pandas
可能非常有用。以
df = pd.DataFrame(my_list, columns=('ItemName', 'ItemCost', 'ItemValue'))
ItemName ItemCost ItemValue
0 Candy 1.0 20.500
1 Soda 3.0 10.250
2 Coffee 1.2 20.335
3 Soap 1.2 11.500
4 Spoon 0.2 2.320
5 Toast 3.2 12.335
6 Toothpaste 3.0 20.500
7 Creamer 0.1 5.500
8 Sugar 2.2 5.200
>>> df[df.ItemCost <= 6]
ItemName ItemCost ItemValue
0 Candy 1.0 20.500
1 Soda 3.0 10.250
2 Coffee 1.2 20.335
3 Soap 1.2 11.500
4 Spoon 0.2 2.320
5 Toast 3.2 12.335
6 Toothpaste 3.0 20.500
7 Creamer 0.1 5.500
8 Sugar 2.2 5.200
>>> df[df.ItemCost <= 6].nlargest(n=5, columns=['ItemValue'])
ItemName ItemCost ItemValue
0 Candy 1.0 20.500
6 Toothpaste 3.0 20.500
2 Coffee 1.2 20.335
5 Toast 3.2 12.335
3 Soap 1.2 11.500
如果需要,您可以先获取nsmallest
中的ItemCost
,然后 然后获取nlargest
df.nsmallest(n=5, columns=['ItemCost']).nlargest(n=5, columns=['ItemValue'])
ItemName ItemCost ItemValue
0 Candy 1.0 20.500
2 Coffee 1.2 20.335
3 Soap 1.2 11.500
7 Creamer 0.1 5.500
4 Spoon 0.2 2.320
答案 1 :(得分:1)
不确定这是否是您的要求
我首先要从my_list创建5个元素的所有可能组合
itertools.combinations(my_list, 5)
然后,我将找到结果中所有可能的组合,其中总项目成本小于或等于6。
f = [element for element in itertools.combinations(my_list, 5) if sum([e[1] for e in element]) <=6]
现在,我将找到itemValue总值最大的那个元素
h = [sum([g[2] for g in e]) for e in f]
最大itemValue的元素的索引为
index = h.index(max(h))
现在,您可以在f中找到该元素。
f[index]
我得到的答案是
Candy 1.0 20.5
Coffee 1.2 20.335
Spoon 0.2 2.32
Toothpaste 3 20.5
Creamer 0.1 5.5
答案 2 :(得分:0)
首先,您要按ItemCost
过滤列表:
可以通过以下方式完成:filtered_generator = filter(lambda x: x[1] <= 6, my_list)
或者以更类似于python的方式filtered_list = [x for x in my_list if x[1] <=6]
要使其成为生成器来节省内存,只需使用括号而不是方括号即可。
然后您要获得n个最大的物品:
nlargest(5, filtered_iter, key=lambda x:x[2])
filtered_iter
可以是列表,也可以是生成器之一。
答案 3 :(得分:0)
from operator import itemgetter
from itertools import combinations
from beautifultable import BeautifulTable
def pretty_print( lst):
table = BeautifulTable()
table.column_headers = ['Item Name','ItemCost','ItemValue']
if lst:
for item_specs in lst:
table.append_row(item_specs)
print(table)
def get_total_cost( lst):
return sum(item_specs[1] for item_specs in lst)
def get_total_Value( lst):
return sum(item_specs[2] for item_specs in lst)
def best_comb( item_list, number_of_items_to_pick, cost_constraint):
k = number_of_items_to_pick
item_list.sort(key=itemgetter(2), reverse=True) # sorting list by ItemValue
k_top_value_item_lst = item_list[:5] # picking top k items from list
total_cost = get_total_cost(k_top_value_item_lst)
def generateCombinations( take_default_val_for_best_result = True):
k_len_combination_list = list(combinations( item_list, k))
if take_default_val_for_best_result:
best_result = []# which meets total itemCost <= 6 condition and have highest total of ItemValue
best_result_sum = [0,0] # ItemCost, ItemValue
else:
best_result = k_top_value_item_lst
best_result_sum = [total_cost, get_total_Value(best_result)]
best_alternative_lst = [] # if there are any other combination which offer same Value for Cost
# ignore first comb as its been already suggested to user
for comb in k_len_combination_list:
temp_sum = [None,None]
temp_sum[0] = get_total_cost( comb)
reset_best = False
if temp_sum[0] <= cost_constraint:
temp_sum[1] = get_total_Value( comb)
if best_result_sum[1] < temp_sum[1]:
reset_best = True
elif best_result_sum[1] == temp_sum[1]:
if temp_sum[0] < best_result_sum[0]:
reset_best = True
elif temp_sum[0] == best_result_sum[0]:
# since ItemValue as well as ItemCost are equivalent to best_result this comb is great alternative
if comb != tuple(best_result):
best_alternative_lst.append(comb)
if reset_best:
best_result = comb
best_result_sum[1] = temp_sum[1]
best_result_sum[0] = temp_sum[0]
print('Best Combination:')
if best_result:
pretty_print(best_result)
else:
print('not found')
if gen_alternative:
print('\nBest Alternative Combination:')
if best_alternative_lst:
for idx,alter_comb in enumerate( best_alternative_lst):
comb_id = idx+1
print('combination_id ',comb_id)
pretty_print(alter_comb)
else:
print('not found')
if total_cost > cost_constraint:
generateCombinations()
else:
if gen_alternative:
generateCombinations(take_default_val_for_best_result = False)
else:
print('Best Combination:')
pretty_print(k_top_value_item_lst)
my_list = [
('Candy', 2.0, 20.5),
('Soda', 1.5, 25.7 ),
('Coffee', 2.4, 25.7 ),
('Soap', 1.2,20),
('Spoon',1.2,20 ),
('Toast',1.2,22 ),
('Toothpaste',0.8, 20 ),
('Creamer',0.8, 22),
('Sugar',2.0, 20.5 ),
]
gen_alternative = input('do you want to generate alternative combinations: y/n ')[0].lower() == 'y'
best_comb( my_list, 5, 6)
回答修改后的列表(以显示其他功能)
do you want to generate alternative combinations: y/n Y
Best Combination:
+------------+----------+-----------+
| Item Name | ItemCost | ItemValue |
+------------+----------+-----------+
| Soda | 1.5 | 25.7 |
+------------+----------+-----------+
| Toast | 1.2 | 22 |
+------------+----------+-----------+
| Creamer | 0.8 | 22 |
+------------+----------+-----------+
| Soap | 1.2 | 20 |
+------------+----------+-----------+
| Toothpaste | 0.8 | 20 |
+------------+----------+-----------+
Best Alternative Combination:
combination_id 1
+------------+----------+-----------+
| Item Name | ItemCost | ItemValue |
+------------+----------+-----------+
| Soda | 1.5 | 25.7 |
+------------+----------+-----------+
| Toast | 1.2 | 22 |
+------------+----------+-----------+
| Creamer | 0.8 | 22 |
+------------+----------+-----------+
| Spoon | 1.2 | 20 | <---
+------------+----------+-----------+
| Toothpaste | 0.8 | 20 |
+------------+----------+-----------+
回答您的原始列表
Best Combination:
+------------+----------+-----------+
| Item Name | ItemCost | ItemValue |
+------------+----------+-----------+
| Candy | 1.0 | 20.5 |
+------------+----------+-----------+
| Toothpaste | 3 | 20.5 |
+------------+----------+-----------+
| Coffee | 1.2 | 20.335 |
+------------+----------+-----------+
| Creamer | 0.1 | 5.5 |
+------------+----------+-----------+
| Spoon | 0.2 | 2.32 |
+------------+----------+-----------+
Best Alternative Combination:
not found
答案 4 :(得分:0)
不确定您要做什么,但是...
如果您尝试根据按最低成本排序的itemcost
检索前x个(5或6),则可以尝试此操作。
x=5
sorted(my_list, key=lambda s : s[2])[:x]
This outputs the following:
[('Spoon', 0.2, 2.32),
('Sugar', 2.2, 5.2),
('Creamer', 0.1, 5.5),
('Soda', 3.0, 10.25),
('Soap', 1.2, 11.5)]
答案 5 :(得分:0)
from itertools import combinations
from functools import reduce
def get_valid_combs(lis):
"find all combinations that cost less than or equal to 6"
for i in combinations(lis, 5):
if reduce(lambda acc, x: acc + x[1], list(i), 0) <= 6:
yield list(i)
my_list = [
('Candy', 1.0, 20.5),
('Soda', 3.0, 10.25),
('Coffee', 1.2, 20.335),
('Soap', 1.2, 11.5),
('Spoon', 0.2, 2.32),
('Toast', 3.2, 12.335),
('Toothpaste', 3, 20.5),
('Creamer', .1, 5.5),
('Sugar', 2.2, 5.2),
]
# find all valid combinations which cost less than 6
valid_combinations = [i for i in get_valid_combs(my_list)]
#top_combinations_sorted = sorted(valid_combinations, key=lambda y: reduce(lambda acc, x: acc + x[2], [0]+y))
# of the valid combinations get the combination with highest total value
best_combination = max(valid_combinations, key=lambda y: reduce(lambda acc, x: acc + x[2], y, 0))
print(best_combination)
输出:
[('Candy', 1.0, 20.5), ('Coffee', 1.2, 20.335), ('Spoon', 0.2, 2.32), ('Toothpaste', 3, 20.5), ('Creamer', 0.1, 5.5)]
答案 6 :(得分:0)
from itertools import combinations
...
total_cost = lambda item: int(sum(c for _, c, _ in item) <= 6) * sum(v for _, _ , v in item)
chosen = max(combinations(my_list, 5), key=total_cost)
Max可以接收指定最大条件的函数。
total_cost函数的int(sum(c表示_,c,_项)<= 6)部分如果组合的总成本小于或等于6则为1,否则为0. < / p>
然后将这部分乘以总值。
combinations(my_list,5)检索具有5个项目的my_list项目的所有可能组合。
打印所选的元素:
('Candy', 1.0, 20.5)
('Coffee', 1.2, 20.335)
('Spoon', 0.2, 2.32)
('Toothpaste', 3, 20.5)
('Creamer', 0.1, 5.5)
答案 7 :(得分:0)
首先过滤列表:
print nlargest(5, [item for item in my_list if item[1]<=6], key=itemgetter(2))
您也可以使用sorted:
sorted([item for item in my_list if item[1]<=6], key=lambda x: x[1], reverse=True)[:5]
上面的过滤器过滤出 ItemCost 大于6的项目,对根据 ItemCost 降序排列的列表进行排序,然后返回前5个元素
答案 8 :(得分:0)
首先使用applicationId
,我们可以从combinations
获得所有5的可能组合。从这里开始,我们可以使用my_list
并仅返回总filter
小于或等于ItemCost
的组合。最后,我们根据哪个组的总数最高6
进行排序,然后选择最大的一组ItemValue
,我们可以使用l2[-1]
,那么它将是reverse = True
从itertools导入组合
l2[0]
l = list(combinations(my_list, 5)) l1 = list(filter(lambda x: sum([i[1] for i in x]) < 6, l)) l2 = sorted(l1, key=lambda x: sum([i[2] for i in x])) print(l2[-1])