我有这个代码,基本上用于csv输入文件,打印出项目/项目的最低成本和餐馆ID。但它在一个输入文件上抛出“KeyError”,但在另一个输入文件上完美地运行(两者都是相同的样式)。有谁能指出哪里错了?感谢
一些重要注意事项:: 挑战::
我的客户不想去多家餐馆。因此,例如,如果他要求“extreme_fajita,jalapeno_poppers,extra_salsa”,那么代码应该打印商店6(它作为组合项目可用),而不是在不同的餐馆周围分散用户需求(即使一些餐馆提供它便宜)。
其次&最重要的是:假设用户要求汉堡。然后,如果某个餐厅'X'给4美元的“汉堡”,而另一家餐馆'Y'给3美元的“汉堡+金枪鱼+豆腐”,那么我们会告诉即使除了用户要求的“汉堡”之外还有额外的物品,用户也可以获得RESTAURANT'Y',但我们很乐意为它们提供额外的物品,只要价格便宜。
def build_shops(shop_text):
shops = {}
for item_info in shop_text:
shop_id,cost,items = item_info.replace('\n', '').split(',')
cost = float(cost)
items = items.split('+')
if shop_id not in shops:
shops[shop_id] = {}
shop_dict = shops[shop_id]
for item in items:
if item not in shop_dict:
shop_dict[item] = []
shop_dict[item].append([cost,items])
return shops
def solve_one_shop(shop, items):
if len(items) == 0:
return [0.0, []]
all_possible = []
first_item = items[0]
for (price,combo) in shop[first_item]:
sub_set = [x for x in items if x not in combo]
price_sub_set,solution = solve_one_shop(shop, sub_set)
solution.append([price,combo])
all_possible.append([price+price_sub_set, solution])
cheapest = min(all_possible, key=(lambda x: x[0]))
return cheapest
def solver(input_data, required_items):
shops = build_shops(input_data)
print shops
result_all_shops = []
for shop_id,shop_info in shops.iteritems():
(price, solution) = solve_one_shop(shop_info, required_items)
result_all_shops.append([shop_id, price, solution])
shop_id,total_price,solution = min(result_all_shops, key=(lambda x: x[1]))
print('SHOP_ID=%s' % shop_id)
sln_str = [','.join(items)+'(%0.2f)'%price for (price,items) in solution]
sln_str = '+'.join(sln_str)
print(sln_str + ' = %0.2f' % total_price)
shop_text = open('input.csv','rb')
#shops = build_shops(shop_text)
#cheapest=solve_one_shop(shops,items)
solver(shop_text,['A'])
input.csv
1,4.00,tuna
1,8.00,tofu
2,5.00,tuna
2,6.50,tofu
3,4.00,chef_salad
3,8.00,steak__sandwich
4,5.00,steak__sandwich
4,2.50,wine_spritzer
5,4.00,extreme_fajita
5,8.00,fancy_eu_water
6,5.00,fancy_eu_water
6,6.00,extreme_fajita+jalapeno_poppers+extra_salsa
但是我收到了这个错误: -
Traceback (most recent call last):
File "working.py", line 56, in <module>
solver(shop_text,['extra_salsa'])
File "working.py", line 42, in solver
(price, solution) = solve_one_shop(shop_info, required_items)
File "working.py", line 27, in solve_one_shop
for (price,combo) in shop[first_item]:
KeyError: 'extra_salsa'
然而,如果我在另一个输入文件上运行它,我得到正确的答案并且不会出现任何错误。
input.csv
1,2.00,A
1,1.25,B
1,2.00,C
1,1.00,D
1,1.00,A+B
1,1.50,A+C
1,2.50,A+D
2,3.00,A
2,1.00,B
2,1.20,C
2,1.25,D
====== OUTPUT ======
{'1': {'A': [[2.0, ['A']], [1.0, ['A', 'B']], [1.5, ['A', 'C']], [2.5, ['A', 'D']]], 'C': [[2.0, ['C']], [1.5, ['A', 'C']]], 'B': [[1.25, ['B']], [1.0, ['A', 'B']]], 'D': [[1.0, ['D']], [2.5, ['A', 'D']]]}, '2': {'A': [[3.0, ['A']]], 'C': [[1.2, ['C']]], 'B': [[1.0, ['B']]], 'D': [[1.25, ['D']]]}}
SHOP_ID=1
A,B(1.00) = 1.00
答案 0 :(得分:2)
在您的商店中没有
extra_salsa
的地方会发生什么?
除了愤怒的莎莎爱客户外,你的脚本不起作用,因为钥匙不存在。
就像您正在检查items
是否为空,您需要检查所请求的项目是否实际在店内:
def solve_one_shop(shop, items):
if len(items) == 0:
return [0.0, []]
all_possible = []
# first_item = items[0]
for item in items:
price,combo = shop.get(item, (0.0,[])) # This will return
# default values when
# the key doesn't exist
让我们从优化加载代码开始:
import csv
from collections import defaultdict
def build_shops(shop_file_name):
shops = defaultdict(list)
with open(shop_file_name, 'r') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
id, cost, items = row
cost = float(cost)
items = items.split('+')
shops[id].append((cost, items,))
return shops
现在我们有一个返回字典的函数,每个键都是一个代表成本和项目列表的元组列表。
接下来,让我们优化求解器:
def solver(shops, required_items):
result_all_shops = []
shops_with_items = []
for i in required_items:
for shop, inventory in shops.iteritems():
for price, items in inventory:
if i in items:
shops_with_items.append((shop, price, i))
if not shops_with_items:
return [] # No shops contained the items
for i in required_items:
result_all_shops.append(min(filter(lambda x: x[2] == i, shops_with_items),
key=lambda x: x[1]))
return result_all_shops
最后,要加载所有内容:
if __name__ == '__main__':
shops = build_shops('input.csv')
items = ['extra_salsa','tofu']
result = solver(shops, items)
if not result:
print('Sorry, no shops contained {}'.format(','.join(items)))
else:
for shop, item, price in result:
print('Shop {} had the item {} for {}'.format(shop,price,item)))