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

时间:2018-10-07 02:53:59

标签: python python-3.x pycharm

Python的新手,才刚刚开始挖掘潜力。在这里,用户输入他们不想要食物的成分。但是问题出在方法只适用于少数几个选项而不适用于其他选项时。这是代码:

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)))

以“辣椒”为例,它可以工作。即使我注释掉不包含它的菜单项,菜单项的输出数量也是正确的。但是像“西红柿”之类的一些似乎没有效仿。我按此顺序列出了列表,以便以后在特定的打印行中使用它们。如果“ removed_from_meal”具有多个元素,则用户创建的列表也将无法正常运行,但我相信它来自第一个问题。

1 个答案:

答案 0 :(得分:0)

这里:

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

您正在(通过.remove()修改要迭代的列表。这是您的(主要)问题。

为简化此问题,请考虑以下代码:

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)

哪个输出:

1
2
Removing 2
4
5
6
7
8
9
10

3发生了什么事?之所以被“跳过”是因为您在迭代列表时修改了列表。 (实际上发生的是,通过删除2,您将索引的3移位了。)

您可以将其更改为:

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

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

话虽如此,我可能会将整个内容重构为更像:

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)