错误:list.remove(x):x 不在列表中,我不明白为啥

Posted

技术标签:

【中文标题】错误:list.remove(x):x 不在列表中,我不明白为啥【英文标题】:Error : list.remove(x) : x not in list, I don't understand why错误:list.remove(x):x 不在列表中,我不明白为什么 【发布时间】:2021-01-21 00:03:22 【问题描述】:

我正在开发一款基于文本的小型游戏,但在从列表中删除元素时遇到了问题。 这是一个运行代码,会引发错误ValueError: list.remove(x): x not in the list,但我不明白为什么。

LVL = 'lvl'
DAMAGE = 'damage'

Items = 
    'Sword':
        LVL : 1,
        DAMAGE : 5,
    ,

    'Wand':
        LVL : 1,
        DAMAGE : 3,
    ,


class player():
    def __init__(self):
        self.inventory = []

class item():
    def __init__(self, name: str, **kwarg):
        self.name = name
        self.dmg = kwarg.get(DAMAGE)
        self.lvl = kwarg.get(LVL)

    def __str__(self):
        return self.name

if __name__ == "__main__":
    user = player()
    for i in Items.keys():
        it = item(i, **Items[i])
        user.inventory.append(it)

    # check user's inventory
    print('Inventory after append items :')
    for i in user.inventory:
        print(i)

    # let's say i want the user to drop items
    items_name = [i for i in Items.keys()]
    items_to_drop = [item(i, **Items[i]) for i in items_name]
    for i in items_to_drop:
        user.inventory.remove(i)

我的猜测是,即使user.inventory 中的项目与items_to_drop 中的项目相同,程序仍将其视为两个不同的变量。在这种情况下,我看不到如何执行我想要的操作,即从user.inventory 中删除项目,因为列表中包含要删除的项目(因为我不能直接循环user.inventory 对吗?)

如果这个问题之前已经回答过,我深表歉意。我已经搜索过了,但没有成功。

【问题讨论】:

你认为 Python 如何比较 item 的两个实例? @timgeb 这是否意味着我必须编写代码?就像在 item 类中覆盖 __eq__ 方法一样?如果没有,我想我不知道.. 你在正确的轨道上,自定义__eq__ 【参考方案1】:

最后,正如评论中所建议的那样,我必须覆盖 item 类的 __eq__() 方法,以便 Python 看到 如果两个 same 项目实际上在user.inventoryitems_to_drop。它有效!

如果需要,我只是做了

def __eq__(self, other):
    return self.name == other.name

【讨论】:

请注意,当前 dmglvl 对于 Python 认为相等的两个项目可能不同。 (但也许这是故意的。) @timgeb 是的,就我而言。但是感谢您的规范!【参考方案2】:

一个简单的解决方案:

    # let's say i want the user to drop items
    items_name = [i for i in Items.keys()]
    items_to_drop = [item(i, **Items[i]) for i in items_name]
    for i in items_to_drop:
        try:
            user.inventory.remove(i)
        except:
            continue

另一个更好的一个:

    # let's say i want the user to drop items
    items_name = [i for i in Items.keys()]
    items_to_drop = [item(i, **Items[i]) for i in items_name]
    invetory_copy = inventory.copy()
    for i in inventory:
        if i in items_to_drop:
            inventory_copy.remove(i)
    inventory = inventory_copy

【讨论】:

不建议在更改列表时循环遍历列表吗?另外,在第一个示例中,我看不出明显的区别......程序将直接用于 except 部分而不更改 user.inventory 。至于第二种,我试过了,还是不行。我认为这与@timgeb 的建议有关。

以上是关于错误:list.remove(x):x 不在列表中,我不明白为啥的主要内容,如果未能解决你的问题,请参考以下文章

获取ValueError:list.remove(x):x尝试从列表中删除值时不在列表中

ValueError: list.remove(x): x 不在列表中(但有)

Python 报错 ValueError list.remove(x) x not in list 解决办法

list.remove(x) 删除超过此列表中的对象[重复]

Python 数据结构

谈谈Python中pop与remove的用法