Python 3.x 使用if语句终止for循环

Python 3.x 使用if语句终止for循环,python-3.x,Python 3.x,我不太确定这个问题怎么说,所以我会继续解释我的具体目标 我正在尝试为文本冒险的用户输入函数实现一个“eat”选项。我希望它检查动词是否为“eat”,检查物品是否在玩家的库存中,检查物品是否可消费,然后-我的目标-显示玩家吃了它(并且只显示一次,见下文)。“eat”选项到目前为止还没有任何功能,我只是测试print语句 我完全知道下面的代码不是处理用户输入的最有效的方法(我仍然在调整处理意外输入的方法),所以我100%接受批评。这只是我最初处理它的方式,我想试着让它发挥作用。我还有几个动词('go

我不太确定这个问题怎么说,所以我会继续解释我的具体目标

我正在尝试为文本冒险的用户输入函数实现一个“eat”选项。我希望它检查动词是否为“eat”,检查物品是否在玩家的库存中,检查物品是否可消费,然后-我的目标-显示玩家吃了它(并且只显示一次,见下文)。“eat”选项到目前为止还没有任何功能,我只是测试print语句

我完全知道下面的代码不是处理用户输入的最有效的方法(我仍然在调整处理意外输入的方法),所以我100%接受批评。这只是我最初处理它的方式,我想试着让它发挥作用。我还有几个动词('go','look','take',等等)可以用,我只是对'eat'有很多麻烦

def user_input(self):
    player = Player()
    while True:
        user_input = input("> ").lower()
        words = user_input.split(" ")
        wordlist = list(words)
        verb = wordlist[0]
        if len(wordlist) == 2:
            noun = wordlist[1]
            if noun not in items:
                print("Somehow '{}' isn't the right word.".format(noun))
                continue
            else:
                pass

            # The above works fine because I don't have
            # an issue with any of the other verbs regarding
            # that bit of code.
            # There's more code between these blocks to:
            # handle if the user enters a noun that is > 1 word,
            # define a few more verbs,
            # then,

        if verb == "eat":
            for item in player.inventory:
                if item.name == noun:
                    if isinstance(item, Consumable):
                        print("You eat the {}.".format(noun))
                        break
                    else:
                        print("You can't eat that!")
                        break
                else:
                    print("You don't have '{}'.".format(noun))
我必须使用for循环(至少,我想我必须这样做),因为我在迭代一个包含对象的列表,而不是字符串,所以我不能只使用for循环

if noun in player.inventory:
(尽管如此,我还是尝试了一百万次,但我花了很长时间才想出解决这个问题的办法)。下面是我对上述代码的具体示例:

class Fists(Weapons):
    def __init__(self):
        self.name = "fists"
        # more instance variables for Fists()

class LeatherWallet(Classy):
    def __init__(self):
        self.name = "leather wallet"
        # more ...

class Pizza(Consumable):
    def __init__(self):
        self.name = "pizza"
        # more ...



class Player():
    def __init__(self):
        self.inventory = [Fists(), LeatherWallet(), Pizza()]
        # other stuff
*吃拳头

You can't eat that!
*吃皮夹

You don't have 'leather wallet'.
You can't eat that!
*吃披萨

You don't have 'pizza'.
You don't have 'pizza'.
You eat the pizza.
从外观上看,它必须是一个简单的修复,因为当它在列表上迭代时,很清楚发生了什么。我只是不知道如何(或者如果可以的话)让for循环先检查条件,然后再打印。冒着听上去愚蠢的危险,我向你们所有人求助

谢谢,如果我能把这个问题/我的目标说得更清楚,请告诉我

编辑:
试图在开头的段落中把目标说得更清楚一些。

你没有说你想要的输出是什么,但我最好的猜测是你不想说“你没有X”不止一次

一种方法是使用一个标志,初始化为false,在找到该项时设置为true。当您退出循环时,标志将告诉您是否找到了它

大概是这样的:

    if verb == "eat":
        found = false
        for item in player.inventory:
            if item.name == noun:
                found = true
                if isinstance(item, Consumable):
                    print("You eat the {}.".format(noun))
                    break
                else:
                    print("You can't eat that!")
                    break
         if !found:
             print("You don't have '{}'.".format(noun))

for
循环有
else
子句,如果循环没有中断退出,这些子句将运行。其思想是,循环正在寻找一个项目,当它找到它时就会中断,
else
子句处理默认情况,即您找不到要查找的内容。循环结束后,循环中使用的变量仍然有效,因此可以在下一位代码中使用找到的(或默认的)变量

在您的情况下,如果将最后一个else子句移出一个级别,则只有在找不到该项时,它才会运行。在示例输出中,将不再打印两行“you not have'pizza1”

for item in player.inventory:
    if item.name == noun:
        if isinstance(item, Consumable):
            print("You eat the {}.".format(noun))
            break
        else:
            print("You can't eat that!")
            break
else:
    print("You don't have '{}'.".format(noun))
    item = None # <-- you can give a default value if you want to
                # use the variable later
然后,for循环被替换为

try:
    item = player.inventory[noun]
    if isinstance(item, Consumable):
        print("You eat the {}.".format(noun))
    else:
        print("You can't eat that!")
except KeyError:
    print("You don't have '{}'.".format(noun))

所以,另一种方法就是让它发挥作用,对吗

if noun in player.inventory:
    ...
你(至少)有两种方法

列表理解 第一个简单的方法是使用:

就这样

自定义类 第二个是创建一个
Inventory
类,该类继承并重写该方法,以便您可以根据需要对它们进行比较

比如:

class Inventory(list):

    def __contains__(self, item):
        """
        Override `list.__contains__`.
        """

        # First, check whether `item` is in the inventory.
        #
        # This is what a normal `list` would do.
        if list.__contains__(self, item):
            return True

        # If we couldn't find the item in the list searching
        # the "normal" way, then try comparing comparing it
        # against the `name` attribute of the items in our
        # inventory.
        for inventory_item in self:
            # Ensure we can do `inventory_item.name` so we don't get
            # an AttributeError.
            if 'name' not in dir(inventory_item):
                continue

            if inventory_item.name == item:
                return True

        return False
然后您可以实例化您的库存,如:

self.inventory = Inventory([Fists(), LeatherWallet(), Pizza()])
请记住,
Inventory
继承自
list
,因此如果您可以执行
list(x)
,那么您也应该能够执行
Inventory(x)
,并获得非常类似的结果(取决于您在类中重写的程度)


您还可以发挥创意,使所有项目从
Item
类继承,在该类中定义方法并使
Pizza()==“Pizza”
简化
库存比较。

这非常有效!这么简单的一个加法。非常感谢。我不知道for…else机制。酷。
class Inventory(list):

    def __contains__(self, item):
        """
        Override `list.__contains__`.
        """

        # First, check whether `item` is in the inventory.
        #
        # This is what a normal `list` would do.
        if list.__contains__(self, item):
            return True

        # If we couldn't find the item in the list searching
        # the "normal" way, then try comparing comparing it
        # against the `name` attribute of the items in our
        # inventory.
        for inventory_item in self:
            # Ensure we can do `inventory_item.name` so we don't get
            # an AttributeError.
            if 'name' not in dir(inventory_item):
                continue

            if inventory_item.name == item:
                return True

        return False
self.inventory = Inventory([Fists(), LeatherWallet(), Pizza()])