python代码在一个文件上工作但在另一个文件上失败

时间:2014-03-25 20:58:24

标签: python csv dictionary

大家好,所以我有这个代码,打印出项目/项目的最低费用和餐馆ID。顾客不想去多家餐馆。例如,如果他要求" A,B"然后代码应该打印商店,提供他们两个,而不是分散不同餐厅的用户需求(即使一些餐厅提供便宜)。

此外,假设用户要求汉堡。然后如果某个餐馆' X'正在给一个"汉堡" 4美元,而另一家餐厅' Y'给予"汉堡+金枪鱼+豆腐" 3美元,然后我们会告诉用户去餐馆' Y',即使它有额外的项目,除了汉堡'用户要求的,但我们很乐意为它们提供额外的物品,只要便宜。

Everythings很好,但是代码在两个输入文件上表现不同(在input.csv上失败但在input-2.csv上运行)具有相同的格式,它为一个提供正确的输出而另一个则失败。这是我需要你帮助修复的唯一一分钟错误。请帮助我,我想我已经撞墙了,不能超越这一切。

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]
    if first_item in shop:
        print "SHOP",shop.get(first_item)
    for (price,combo) in shop[first_item]:
        #print "items,combo=",items,combo
        sub_set = [x for x in items if x not in combo]
        #print "sub_set=",sub_set
        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-1.csv','rb')    
solver(shop_text,['burger'])

===== input-1.csv ===== restaurant_id,price,item

1,2.00,burger
1,1.25,tofulog
1,2.00,tofulog
1,1.00,chef_salad
1,1.00,A+B
1,1.50,A+CCC
1,2.50,A
2,3.00,A
2,1.00,B
2,1.20,CCC
2,1.25,D

=====输出&错误====:

{'1': {'A': [[1.0, ['A', 'B']], [1.5, ['A', 'CCC']], [2.5, ['A', 'D']]], 'B': [[1.0, ['A', 'B']]], 'D': [[2.5, ['A', 'D']]], 'chef_salad': [[1.0, ['chef_salad']]], 'burger': [[2.0, ['burger']]], 'tofulog': [[1.25, ['tofulog']], [2.0, ['tofulog']]], 'CCC': [[1.5, ['A', 'CCC']]]}, '2': {'A': [[3.0, ['A']]], 'B': [[1.0, ['B']]], 'D': [[1.25, ['D']]], 'CCC': [[1.2, ['CCC']]]}}
SHOP [[2.0, ['burger']]]
Traceback (most recent call last):
  File "work.py", line 55, in <module>
    solver(shop_text,['burger'])
  File "work.py", line 43, in solver
    (price, solution) = solve_one_shop(shop_info, required_items)
  File "work.py", line 26, in solve_one_shop
    for (price,combo) in shop[first_item]:
KeyError: 'burger'

如果我在input-2.csv上运行相同的代码,并查询求解器(shop_text,[&#39; A&#39;,&#39; CCC&#39;]),我得到正确的结果< / p>

=====输入2.csv ==

1,2.00,A
1,1.25,B
1,2.00,B
1,1.00,A
1,1.00,A+B
1,1.50,A+CCC
1,2.50,A+D
2,3.00,A
2,1.00,B
2,1.20,CCC
2,1.25,D

======输出====

{'1': {'A': [[2.0, ['A']], [1.0, ['A']], [1.0, ['A', 'B']], [1.5, ['A', 'CCC']], [2.5, ['A', 'D']]], 'B': [[1.25, ['B']], [2.0, ['B']], [1.0, ['A', 'B']]], 'D': [[2.5, ['A', 'D']]], 'CCC': [[1.5, ['A', 'CCC']]]}, '2': {'A': [[3.0, ['A']]], 'B': [[1.0, ['B']]], 'D': [[1.25, ['D']]], 'CCC': [[1.2, ['CCC']]]}}
SHOP [[2.0, ['A']], [1.0, ['A']], [1.0, ['A', 'B']], [1.5, ['A', 'CCC']], [2.5, ['A', 'D']]]
SHOP [[1.5, ['A', 'CCC']]]
SHOP [[1.5, ['A', 'CCC']]]
SHOP [[1.5, ['A', 'CCC']]]
SHOP [[1.5, ['A', 'CCC']]]
SHOP [[3.0, ['A']]]
SHOP [[1.2, ['CCC']]]
SHOP_ID=1
A,CCC(1.50) = 1.50

2 个答案:

答案 0 :(得分:3)

如果你这样做,你可以找出错误:

solve_one_shop方法中,在shop行后打印字典first_item = items[0]。这样做会打印出来:

{'A': [[3.0, ['A']]], 'B': [[1.0, ['B']]], 'D': [[1.25, ['D']]], 'CCC': [[1.2, ['CCC']]]}

因此,burger不是其关键字之一,因此会引发KeyError

添加此行: 2,1.25,burgerinput.csv文件的末尾,您的代码运行正常。

在try except块中读取shop字典中的值,以处理项目可能不存在的情况。

注意:
在方法build_shops中,行:

shop_id,cost,items = item_info.replace('\n', '').split(',')

虽然剥离了换行符,但它并没有剥离回车。要解决这个问题,请执行以下操作:

shop_id,cost,items = item_info.replace('\n', '').replace('\r', '').split(',')

希望这有帮助。

答案 1 :(得分:2)

我想我已经修好了......

solve_one_shop

for循环应仅在if内发生,否则您将获得KeyError。另外,我更改了它,只有在all_possible包含任何内容时才会返回(空list评估为False

编辑为防止TypeError我已完成分配给临时值this_subset而其余的循环仅发生,而不是None

def solve_one_shop(shop, items):
    if len(items) == 0:
        return [0.0, []]
    all_possible = []
    first_item = items[0]
    if first_item in shop:
        for (price,combo) in shop[first_item]:
            sub_set = [x for x in items if x not in combo]
            this_subset = solve_one_shop(shop, sub_set)
            if this_subset is not None:
                price_sub_set,solution = this_subset
                solution.append([price,combo])
                all_possible.append([price+price_sub_set, solution])

    if all_possible:
        cheapest = min(all_possible, key=(lambda x: x[0]))
        return cheapest

求解器

我已将solve_one_shop的返回值分配给中间变量。如果是None,则商店不会添加到result_all_shops

修改如果result_all_shops为空,则打印邮件而不是尝试查找min

def solver(input_data, required_items):
    shops = build_shops(input_data)
    result_all_shops = []
    for shop_id,shop_info in shops.iteritems():
        this_shop = solve_one_shop(shop_info, required_items)
        if this_shop is not None:
            (price, solution) = this_shop
            result_all_shops.append([shop_id, price, solution])

    if result_all_shops:
        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)
    else:
        print "Item not available"