简体   繁体   English

检查用户创建的列表项是否存在于预制列表中的问题

[英]Problem with checking if user-created list items exist in a pre-made list

So new to Python and just started working out the potentials. 对Python来说还很陌生,因此才刚刚开始挖掘潜力。 Here, the user types in the ingredients they don't want their food to have. 在这里,用户输入他们不想要食物的成分。 But the problem comes when the method works with a few of the options and doesn't with the rest. 但是问题出在方法只适用于少数几个选项而不适用于其他选项时。 Here's the code: 这是代码:

menu = []
pepper = "pepper"
salt = "salt"
meat = "meat"
chicken = "chicken"
tomato = "tomato"
cucumber = "cucumber"
tye = "tye"
food_1 = [pepper, salt, meat]
food_2 = [chicken, tomato, cucumber]
food_3 = [pepper, chicken, tomato]
food_4 = [salt, tomato, cucumber]
food_5 = [meat, tomato]
food_6 = [pepper, tye]
# pepper is used 3 times.
# salt is used 2 times,
# meat is used 2 times.
# chicken is used 2 times.
# tomato is used 4 times.
# cucumber is used 2 times.
# tye is used 1 time.
menu.append(food_1)
menu.append(food_2)
menu.append(food_3)
menu.append(food_4)
menu.append(food_5)
menu.append(food_6)

bad_ingredients = ""
removed_from_meal = []
while bad_ingredients is not "0":
    bad_ingredients = input("Please tell me what foods you don't like. When you're finished, type 0 to quit this: ")
    removed_from_meal.append(bad_ingredients)
    if removed_from_meal.__contains__("0"):
        removed_from_meal.remove("0")  # removing the 0 used to exit the loop from the list.
print("You have asked to remove {} from your food.".format(removed_from_meal))

for food in menu:
    if any(elem in removed_from_meal for elem in food):
        menu.remove(food)
print("You can now choose {} foods from the menu.".format(len(menu)))

Take "pepper" for example and it works. 以“辣椒”为例,它可以工作。 Even when I comment out the ones not containing it, the output number of menu items is correct. 即使我注释掉不包含它的菜单项,菜单项的输出数量也是正确的。 But a few like "tomato" doesn't seem to follow. 但是像“西红柿”之类的一些似乎没有效仿。 I made the lists in this order to use them later on in specific print lines. 我按此顺序列出了列表,以便以后在特定的打印行中使用它们。 The user-made list also doesn't function quite well if the "removed_from_meal" has got more than one element but I believe it comes from the first problem. 如果“ removed_from_meal”具有多个元素,则用户创建的列表也将无法正常运行,但我相信它来自第一个问题。

Here: 这里:

for food in menu:
    if any(elem in removed_from_meal for elem in food):
       menu.remove(food)

You're modifying (by .remove() ) a list that you're iterating over. 您正在修改(通过.remove() )要迭代的列表。 This is your (main) issue. 这是您的(主要)问题。

To simplify the issue, consider the following code: 为了简化问题,请考虑以下代码:

lst = [1,2,3,4,5,6,7,8,9,10]

for x in lst:
    print(x)
    if x == 2:
        print("Removing 2")
        lst.remove(x)

Which outputs: 哪个输出:

1
2
Removing 2
4
5
6
7
8
9
10

What happened to 3? 3怎么了? It was "skipped" because you modified the list while iterating over it. 之所以被“跳过”是因为您在迭代列表时修改了列表。 (What actually happened is, by removing 2, you shifted the index of 3). (实际上发生的是,通过删除2,将索引的3移位了)。

You could change this to something like: 您可以将其更改为:

acceptable_meals = []
for meal in menu:
    if not any(food in removed_from_meal for food in meal):
        acceptable_meals.append(meal)

or 要么

acceptable_meals = []
for meal in menu:
    if any(food in removed_from_meal for food in meal):
        continue
    acceptable_meals.append(meal)

That being said, I might refactor the entire thing to look something more like: 话虽这么说,我可能会将整个内容重构为更像:

pepper = "pepper"
salt = "salt"
meat = "meat"
chicken = "chicken"
tomato = "tomato"
cucumber = "cucumber"
tye = "tye"

# We can define the menu all at once, as a list of lists, instead of appending 
#   multiple separate sublists.
menu = [
    [pepper, salt, meat],
    [chicken, tomato, cucumber],
    [pepper, chicken, tomato],
    [salt, tomato, cucumber],
    [meat, tomato],
    [pepper, tye]
]

removed_from_meal = []
while True:
    bad_ingredient = input("Please tell me what foods you don't like. When you're finished, type 0 to quit this: ")
    if bad_ingredient == "0":
        break
    # Otherwise, add it to the food "blacklist"
    removed_from_meal.append(bad_ingredient)

print("You have asked to remove {} from your meal.".format(removed_from_meal))

# Create a new list, which we'll populate if none of the food it contains is blacklisted
acceptable_meals = []
for meal in menu:
    if not any(food in removed_from_meal for food in meal):
        acceptable_meals.append(meal)

print("You can now choose {} meals from the menu:".format(len(acceptable_meals)))
for meal in acceptable_meals:
    print(meal)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM