You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.14中Mazo类eliminaCarta方法删除指定元素异常问题

问题:Python3中删除扑克牌列表元素时误删第一个元素

这是我在本站的第一个问题。我尝试将Python 2中的eliminaCarta函数适配到Python 3.14,这个函数属于Mazo类,作用是接收Carta类实例并从Mazo的列表中删除该实例。但实际运行时,函数删除的是列表第一个元素而非目标元素,我找不到问题所在。

相关代码如下:

import random

class Carta:
    listaDePalos = ["Tréboles", "Diamantes", "Corazones", "Picas"]
    listaDeValores = ["nada", "As", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Sota", "Reina", "Rey"]
    
    def __init__(self, palo=0, valor=0):
        self.palo = palo
        self.valor = valor

    def __str__(self):
        return (self.listaDeValores[self.valor] + " de " + self.listaDePalos[self.palo])
    
    def __lt__(self, other):
        # controlar el palo
        if self.palo > other.palo: return 1
        if self.palo < other.palo: return -1

        if self.valor == 1 and self.valor != other.valor: return 1
        if other.valor == 1 and self.valor != other.valor: return -1
        # si son del mismo palo, controlar el valor
        if self.valor > other.valor: return 1 
        if self.valor < other.valor: return -1
        # los valores son iguales, es un empate
        return 0

    def __gt__(self, other):
        # controlar el palo
        if self.palo > other.palo: return 1
        if self.palo < other.palo: return -1

        if self.valor == 1 and self.valor != other.valor: return 1
        if other.valor == 1 and self.valor != other.valor: return -1
        # si son del mismo palo, controlar el valor
        if self.valor > other.valor: return 1
        if self.valor < other.valor: return -1
        # los valores son iguales, es un empate
        return 0

    def __eq__(self, other):
        if self.valor == other.valor: return 1
        else: return -1

class Mazo:
    def __init__(self):
        self.cartas = []
        for palo in range(4):
            for valor in range(1, 14):
                self.cartas.append(Carta(palo, valor))

    def muestraMazo(self):
        for carta in self.cartas:
            print(carta)

    def __str__(self):
        s = ""
        for i in range(len(self.cartas)):
            s = s + " "*i + str(self.cartas[i]) + "\n"
        return s

    def mezclar(self):
        nCartas = len(self.cartas)
        for i in range(nCartas):
            j = random.randrange(i, nCartas)
            self.cartas[i], self.cartas[j] = self.cartas[j], self.cartas[i]        

    def __contains__(self, item):
        return item in self.items

    def eliminaCarta(self, carta):
        if carta in self.cartas:
            self.cartas.remove(carta)
            return 1
        else:
            return 0

初始打印Mazo实例时输出正常:

As de Tréboles
 2 de Tréboles
  3 de Tréboles
   4 de Tréboles
    5 de Tréboles
     6 de Tréboles
      7 de Tréboles
       8 de Tréboles
        9 de Tréboles
         10 de Tréboles
          Sota de Tréboles
           Reina de Tréboles
            Rey de Tréboles
             As de Diamantes
              2 de Diamantes
               3 de Diamantes        
                4 de Diamantes       
                 5 de Diamantes      
                  6 de Diamantes     
                   7 de Diamantes    
                    8 de Diamantes   
                     9 de Diamantes  
                      10 de Diamantes
                       Sota de Diamantes
                        Reina de Diamantes
                         Rey de Diamantes
                          As de Corazones
                           2 de Corazones
                            3 de Corazones
                             4 de Corazones
                              5 de Corazones
                               6 de Corazones
                                7 de Corazones
                                 8 de Corazones
                                  9 de Corazones
                                   10 de Corazones
                                    Sota de Corazones
                                     Reina de Corazones
                                      Rey de Corazones
                                       As de Picas
                                        2 de Picas
                                         3 de Picas
                                          4 de Picas
                                           5 de Picas
                                            6 de Picas
                                             7 de Picas
                                              8 de Picas
                                               9 de Picas
                                                10 de Picas
                                                 Sota de Picas
                                                  Reina de Picas
                                                   Rey de Picas

但执行以下代码:

carta = Carta(1,13)

mazo = Mazo()

mazo.eliminaCarta(carta)

print(mazo)

结果却删除了列表第一个元素(As de Tréboles),而本应删除的是Rey de Diamantes:

2 de Tréboles
 3 de Tréboles
  4 de Tréboles
   5 de Tréboles
    6 de Tréboles
     7 de Tréboles
      8 de Tréboles
       9 de Tréboles
        10 de Tréboles
         Sota de Tréboles
          Reina de Tréboles
           Rey de Tréboles
            As de Diamantes
             2 de Diamantes
              3 de Diamantes
               4 de Diamantes
                5 de Diamantes
                 6 de Diamantes
                  7 de Diamantes
                   8 de Diamantes
                    9 de Diamantes
                     10 de Diamantes
                      Sota de Diamantes
                       Reina de Diamantes
                        Rey de Diamantes
                         As de Corazones
                          2 de Corazones
                           3 de Corazones
                            4 de Corazones
                             5 de Corazones
                              6 de Corazones
                               7 de Corazones
                                8 de Corazones
                                 9 de Corazones
                                  10 de Corazones
                                   Sota de Corazones
                                    Reina de Corazones
                                     Rey de Corazones
                                      As de Picas
                                       2 de Picas
                                        3 de Picas
                                         4 de Picas
                                          5 de Picas
                                           6 de Picas
                                            7 de Picas
                                             8 de Picas
                                              9 de Picas
                                               10 de Picas
                                                Sota de Picas
                                                 Reina de Picas
                                                  Rey de Picas

问题原因与解决方案

核心问题

  1. Carta类的__eq__方法实现错误:Python中__eq__必须返回布尔值True或False,但你的代码返回1或-1。当列表执行in判断和remove操作时,非零数值都会被视为True,导致第一个元素就被判定为匹配目标,从而被误删。此外,当前__eq__只比较了牌的点数(valor),没有比较花色(palo),逻辑本身就不正确。

  2. Mazo类的__contains__方法笔误:方法中写的是return item in self.items,但Mazo类根本没有self.items属性,正确应该是self.cartas。不过这个笔误没影响到eliminaCarta的判断,因为函数里直接用了carta in self.cartas,但这个方法本身需要修正。

修正代码

1. 修正Carta类的__eq__方法

def __eq__(self, other):
    # 只有花色和点数都相同时,两张牌才相等
    return self.palo == other.palo and self.valor == other.valor

2. 修正Mazo类的__contains__方法

def __contains__(self, item):
    return item in self.cartas

3. (可选但建议)修正比较运算符__lt__和__gt__

Python3中比较运算符应该返回布尔值,而非1或-1,虽然这不是当前问题的直接原因,但为了代码规范和兼容性,建议修正:

def __lt__(self, other):
    # 先比较花色
    if self.palo != other.palo:
        return self.palo < other.palo
    # 花色相同,A的优先级最高(A比其他牌大)
    if self.valor == 1:
        return False  # A不小于任何非A牌
    if other.valor == 1:
        return True   # 非A牌小于A
    # 其他情况比较点数
    return self.valor < other.valor

def __gt__(self, other):
    if self.palo != other.palo:
        return self.palo > other.palo
    if self.valor == 1:
        return True
    if other.valor == 1:
        return False
    return self.valor > other.valor

验证效果

修正后运行测试代码,Carta(1,13)(方块K)会被正确从牌堆中移除,不会再误删黑桃A。

内容的提问来源于stack exchange,提问作者Matias Alvarez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 15:57:27