将列表与 Python 中的嵌套列表进行比较

compare list with a nested list in python

提问人:jstone 提问时间:11/17/2023 最后编辑:jstone 更新时间:11/18/2023 访问量:74

问:

我需要一个函数来比较两个列表并从第一个列表提取值。 我有一个清单。

shopping_list = [['1', 'shirt', '8.99'], ['2', 'pants', '10.99'], ['3', 'socks', '5.99'], ['4', 'hat', '9.99'], ['5', 'shoes', '14.99']]

我有一个最终的清单

cart = ['shirt', 'pants', 'shirt']

我需要知道如何从第一个列表中提取第二个列表中项目的值并将它们相加。 (8.99 + 10.99 + 8.99 = 28.97)

def subtotal(shopping_list, cart):
    total = 0
    for i in range(len(shopping_list)):
        if shopping_list[i][0] == i:
            item_name = shopping_list[i][1]
            for j in cart:
                if j == item_name:
                    total += int(shopping_list[i][2])
            print('Your subtotal is ', total)
    return total

绝对没有给我任何东西

嵌套 Python 列表 函数

评论

0赞 pho 11/17/2023
请注意,它是一个元组,而不是一个列表。另外,不要忘记字符串周围的引号。最后,请参阅格式设置帮助。代码块是通过在代码前后的行上键入三个反引号 () 来创建的。cart = burrito, stir fry, burritocart```
1赞 Brian61354270 11/17/2023
应该检查什么?if menu_list[i][0] == i:
0赞 pho 11/17/2023
您还应该阅读 ericlippert.com/2014/03/05/how-to-debug-small-programs,了解如何使用调试器单步执行程序,逐行检查其操作以捕获任何问题。
1赞 S3DEV 11/17/2023
在您的情况下,永远不会评估为 .因为,例如,.if menu_list[i][0] == iTrue1 != '1'
0赞 pho 11/17/2023
您必须为菜单使用列表吗?字典是更好的数据结构

答:

1赞 pho 11/17/2023 #1

你的代码有很多问题,所以我建议一种不同的方法:对于你的菜单,使用字典而不是列表。字典允许您按键(项目名称)查找值(在本例中为价格),而无需遍历整个字典来查找它。您可以将 转换为字典一次,然后继续使用它:menu_list

from decimal import Decimal
menu_dict = {item[1]: Decimal(item[2]) for item in menu_list}

这将遍历 中的每一个。每个列表本身都是一个包含三个字符串的列表:索引、项目名称和项目的价格。字典推导创建一个字典,其键是 的第二个元素(即它的名字,),其值是 的第三个元素(即它的价格,转换为小数: )。您也可以使用 代替 ,但请参阅下面的注释 3 了解为什么不应该这样做。itemmenu_listitemitemitem[1]itemDecimal(item[2])floatDecimal

这将导致以下字典给定您的:menu_list

{
 'burrito': Decimal('6.99'),
 'stir fry': Decimal('7.99'),
 'hamburger': Decimal('8.99'),
 'cheeseburger': Decimal('9.99'),
 'french fries': Decimal('4.99')
}

接下来,让我们改进您的函数:subtotal

def subtotal(menu, cart): 
    total = 0
    for item_name in cart:
        try:
            total += menu[item_name]
        except KeyError:
            print(f"Sorry, we don't sell {item_name}")

    return total

这里,需要菜单字典和购物车列表。 此函数遍历列表中的每个函数,并尝试在字典中查找其值。如果在字典中找到,则价格将添加到 。如果没有,则由 python 引发。然后,该子句会捕获此消息,并打印一条不错的消息,并且不会将该项目的任何内容添加到 .subtotalitem_namecartmenuitem_nametotalKeyErrorKeyErrorexcept KeyErrortotal

注意:如果您不想打印消息,而是静默地不添加任何内容,则可以将整个块替换为 .字典的方法尝试返回第一个参数给出的键,如果失败,则返回提供的第二个参数。try..excepttotal += menu.get(item_name, 0).get

cart = ['burrito', 'stir fry', 'burrito', 'tiramisu']

cart_subtotal = subtotal(menu_dict, cart)

现在,是预期值,并打印了一条消息,指示提拉米苏不在菜单上。cart_subtotal21.97


如果我逐行指出你的代码存在的问题,也许它会帮助你学习。

在我们开始编码之前,您需要考虑您使用的方法是否有任何不必要的低效率。例如,在列表中查找项目时,您需要遍历(可能)整个列表。这在 python 中是一个缓慢的操作,但如果您多次这样做,可能会显着减慢您的代码速度。在您的方法中,您循环遍历每个项目,然后尝试通过循环访问购物车本身来在购物车中找到该项目。如果两者都足够大,则代码将变慢到爬网速度。这里的另一种方法是使用字典,就像我一样。字典提供基于键的值的快速查找,因此您无需遍历整个列表来查找每个项目。menu_listmenu_listcart

现在,让我们从您的函数开始:

def subtotal(menu_list, cart):
    total = 0
    for i in range(len(menu_list)):
        if menu_list[i][0] == i:
            item_name = menu_list[i][1]
            for j in cart:
                if j == item_name:
                    total += int(menu_list[i][2])
            print('Your subtotal is ', total)
    return total
  1. 行 : 在 python 中,我们遍历列表 () 中的项目,而不是遍历列表 () 的索引,然后使用该索引 () 访问元素。for i in range(len(menu_list))for item in my_listfor index in range(len(my_list))item = my_list[index]
  2. 行 : 始终是一个字符串。 是一个整数。这两件事永远不会相提并论。更重要的是,的值从 1 开始,但从 0 开始,所以即使字符串可以等于整数,这个条件也永远不会成立。由于此条件永远不会成立,因此永远不会执行函数的其余部分。无论如何,这次检查的目的是什么?if menu_list[i][0] == imenu_list[i][0]imenu_list[i][0]range
  3. 如果我们忽略上面的问题,你循环过来查找(你以正确的(pythonic)方式进行这个循环)。当您在购物车中找到同名商品时,将菜单中的价格转换为 ,但这些价格不是整数,它们包含小数。您应该将它们转换为 或 []s(请参阅为什么不使用 Double 或 Float 来表示货币?为什么首选)cartitem_nameintfloatDecimalDecimal

评论

1赞 S3DEV 11/17/2023
也许可以更改为防止 .只是一个想法。total += menu[item_name]total += menu.get(item_name, 0)KeyError
1赞 pho 11/17/2023
@S3DEV 没错,但我走了这条路线来说明当密钥不存在时会发生什么,以及如何打印消息而不是默默地向总数添加任何内容。我在答案中添加了一个注释。try..except
0赞 jstone 11/17/2023
所有这些都非常有帮助。
-1赞 Wooop 11/17/2023 #2

在这种情况下,使用字典而不是数组会更方便。这样,可以使用每个项目的键更快地执行搜索以获取其价格。

menu_list = {
    "burrito": 6.99,
    "stir fry": 7.99,
    "hamburger": 8.99
}

cart = ['burrito', 'stir fry', 'burrito']

total = 0
for elements in cart:
    total += menu_list[elements]

print(total)
# 21.97
# 
# Process finished with exit code 0