Python代码出现list index out of range错误的解决及函数交互疑问
Hey there! Let's work through your problem step by step—first the list index out of range error, then the function interaction logic, and finally fixes to get your code running smoothly.
Why the list index out of range Error Happens
That error pops up because your lookup_product_by_id function tries to access matching_products[0] even when matching_products is an empty list. Here's exactly why that happens:
- Your product IDs in the
productslist are integers (like1,2), but when you useinput(), the user's input is a string (like"1"). Comparing a string to an integer (e.g.,"1" == 1) always returnsFalse. - If a user inputs an ID that doesn't exist (or a non-number), the list comprehension
[product for product in products if product["id"] == product_id]creates an empty list. Trying to grab the first element of an empty list with[0]throws the index error.
Understanding return matching_products[0] & product = lookup_product_by_id(product_id)
Let's break down how these lines work together like a team:
The
lookup_product_by_idfunction:- It takes a
product_idas input, then scans through yourproductslist to find any product where theidmatches the input value. - The result is stored in
matching_products—since all product IDs are unique, this list will either have one product dictionary (if a match is found) or be empty (if no match exists). return matching_products[0]sends back that single matching product dictionary to wherever the function was called.
- It takes a
The
product = lookup_product_by_id(product_id)line:- When you call the function with a specific ID, it runs the logic above and returns either a product dictionary or causes an error (if no match is found).
- The returned value gets assigned to the
productvariable, which lets you access the product's details likeproduct["name"]orproduct["price"].
Fixes to Resolve the Error & Improve Your Code
Here's how to adjust your code to handle invalid inputs and avoid crashes:
1. Convert Input to Integer & Validate User Input
First, make sure you're comparing apples to apples by converting the user's input string to an integer. Also, add checks to catch non-numeric inputs:
products = [ {"id":1, "name": "Chocolate Sandwich Cookies", "department": "snacks", "aisle": "cookies cakes", "price": 3.50}, {"id":2, "name": "All-Seasons Salt", "department": "pantry", "aisle": "spices seasonings", "price": 4.99}, {"id":3, "name": "Robust Golden Unsweetened Oolong Tea", "department": "beverages", "aisle": "tea", "price": 2.49}, {"id":4, "name": "Smart Ones Classic Favorites Mini Rigatoni With Vodka Cream Sauce", "department": "frozen", "aisle": "frozen meals", "price": 6.99}, {"id":5, "name": "Green Chile Anytime Sauce", "department": "pantry", "aisle": "marinades meat preparation", "price": 7.99}, {"id":6, "name": "Dry Nose Oil", "department": "personal care", "aisle": "cold flu allergy", "price": 21.99}, {"id":7, "name": "Pure Coconut Water With Orange", "department": "beverages", "aisle": "juice nectars", "price": 3.50}, {"id":8, "name": "Cut Russet Potatoes Steam N' Mash", "department": "frozen", "aisle": "frozen produce", "price": 4.25}, {"id":9, "name": "Light Strawberry Blueberry Yogurt", "department": "dairy eggs", "aisle": "yogurt", "price": 6.50}, {"id":10, "name": "Sparkling Orange Juice & Prickly Pear Beverage", "department": "beverages", "aisle": "water seltzer sparkling water", "price": 2.99}, {"id":11, "name": "Peach Mango Juice", "department": "beverages", "aisle": "refrigerated", "price": 1.99}, {"id":12, "name": "Chocolate Fudge Layer Cake", "department": "frozen", "aisle": "frozen dessert", "price": 18.50}, {"id":13, "name": "Saline Nasal Mist", "department": "personal care", "aisle": "cold flu allergy", "price": 16.00}, {"id":14, "name": "Fresh Scent Dishwasher Cleaner", "department": "household", "aisle": "dish detergents", "price": 4.99}, {"id":15, "name": "Overnight Diapers Size 6", "department": "babies", "aisle": "diapers wipes", "price": 25.50}, {"id":16, "name": "Mint Chocolate Flavored Syrup", "department": "snacks", "aisle": "ice cream toppings", "price": 4.50}, {"id":17, "name": "Rendered Duck Fat", "department": "meat seafood", "aisle": "poultry counter", "price": 9.99}, {"id":18, "name": "Pizza for One Suprema Frozen Pizza", "department": "frozen", "aisle": "frozen pizza", "price": 12.50}, {"id":19, "name": "Gluten Free Quinoa Three Cheese & Mushroom Blend", "department": "dry goods pasta", "aisle": "grains rice dried goods", "price": 3.99}, {"id":20, "name": "Pomegranate Cranberry & Aloe Vera Enrich Drink", "department": "beverages", "aisle": "juice nectars", "price": 4.25} ] product_ids = [] while True: product_id_input = input("Hey please input a product identifier: ") if product_id_input == "done": break # Try converting input to integer try: product_id = int(product_id_input) product_ids.append(product_id) except ValueError: print(f"Oops, '{product_id_input}' isn't a valid number. Please enter a numeric ID or 'done'.")
2. Update the Lookup Function to Handle Missing Products
Modify the function to check if a product was found before trying to return it:
def lookup_product_by_id(product_id): matching_products = [product for product in products if product["id"] == product_id] # Only return the product if we found a match if matching_products: return matching_products[0] else: print(f"Warning: No product found with ID {product_id}. Skipping this entry.") return None
3. Adjust the Total Calculation to Skip Invalid Entries
Make sure you only process valid products when calculating the total:
raw_total = 0 for product_id in product_ids: product = lookup_product_by_id(product_id) if product is not None: raw_total += product["price"] # Format the price for cleaner output print(f"{product['id']} {product['name']} ${product['price']:.2f}") # Optional: Print the final total print(f"\nTotal: ${raw_total:.2f}")
With these changes, your code will handle non-numeric inputs, invalid product IDs, and avoid the index error entirely.
内容的提问来源于stack exchange,提问作者Jay Jakyung Koo

