类方法中的remove函数有问题
这是我在这个网站上的第一个问题。
问题是,我试图把一个Python 2的函数适配到Python 3.14,函数名为eliminaCarta,它接收一个名为carta的类,并从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
carta = Carta(1,1)
mazo = Mazo()
print(mazo)
打印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
但是,当调用mazo.eliminaCarta(carta)
carta = Carta(1,13)
mazo = Mazo()
mazo.eliminaCarta(carta)
print(mazo)
时,结果是:
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
第一个元素被删除,而应该删除的元素是 "Rey de Diamantes"
解决方案
.remove() 使用 Carta.__eq__ 来检查要删除哪张牌,并且有两个问题
- 它还需要比较
self.palo == other.palo bool(1)给出True,而bool(-1)也给出True。
bool(0)给出False。但最好使用True/False代替1/-1/0
def __eq__(self, other):
if (self.valor == other.valor) and (self.palo == other.palo):
return True
else:
return False
但你可以写得更短一些(因为 == 和 and 已经给出 True/False)
def __eq__(self, other):
return (self.valor == other.valor) and (self.palo == other.palo)
(正如 @MarcePuente在评论中提到的,你可以在没有括号的情况下写。我用它来让可读性稍微好一些。有时它更清楚地展示哪些元素是先被计算的)
现在 self.cartas.remove(carta) 可以正确工作。
顺便说一句:
在其他函数中,你也应该使用 True/False 代替 1/-1
正如 @JonSG指出,__contains__ 存在错误——应该是 self.cartas 而不是 self.items
@JonSG还指出 __lt__() 和 __gt__() 应该把 > 和 < 交换,但你在两处的代码完全一样。
我也不清楚为什么 __lt__() 和 __gt__() 会同时有 if self.valor == 1 ... 和 if other.valor == 1。
关于 mezclar 的简短版本
def mezclar(self):
random.shuffle(self.cards)
在其他修改后的版本:
import random
class Card:
# fmt: off
all_colors = ["Clubs", "Diamonds", "Hearts", "Spades"]
all_values = ["nothing", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"]
# fmt: on
def __init__(self, color=0, value=0):
self.color = color
self.value = value
def __str__(self):
return self.all_values[self.value] + " of " + self.all_colors[self.color]
def __lt__(self, other):
if self.color > other.color:
return True
if self.color < other.color:
return False
# the same color
return self.value < other.value
def __gt__(self, other):
if self.color < other.color:
return True
if self.color > other.color:
return False
# the same color
return self.value > other.value
def __eq__(self, other):
return (self.value == other.value) and (self.color == other.color)
def __le__(self, other):
return (self < other) or (self == other)
def __ge__(self, other):
return (self > other) or (self == other)
class Deck:
def __init__(self):
self.cards = []
for color in range(4):
for value in range(1, 14):
self.cards.append(Card(color, value))
def display(self):
# for card in self.cards:
# print(card)
print(self)
def __str__(self):
s = ""
for card in self.cards:
s += f"{card}\n"
return s
def shuffle(self):
random.shuffle(self.cards)
def __contains__(self, item):
return item in self.cards
def remove(self, card):
if card in self.cards:
self.cards.remove(card)
# --- main ---
deck = Deck()
# print(deck)
card1 = Card(1, 13)
print(f"card1: '{card1}'")
print(f"deck contains '{card1}':", card1 in deck)
print(f"removing ... '{card1}'")
deck.remove(card1)
print(f"deck contains '{card1}':", card1 in deck)
# print(deck)
# deck.shuffle()
# print(deck)
print(f"'{card1}' and '{card1}'")
print("== :", card1 == card1)
print("> :", card1 > card1)
print("< :", card1 < card1)
print(">= :", card1 >= card1)
print("<= :", card1 <= card1)
card2 = Card(3, 10)
print(f"card2: '{card2}'")
print(f"'{card1}' and '{card2}'")
print("== :", card1 == card2)
print("> :", card1 > card2)
print("< :", card1 < card2)
print(">= :", card1 >= card2)
print("<= :", card1 <= card2)
# deck.display()
card1: 'King of Diamonds'
deck contains 'King of Diamonds': True
removing ... 'King of Diamonds'
deck contains 'King of Diamonds': False
'King of Diamonds' and 'King of Diamonds'
== : True
> : False
< : False
>= : True
<= : True
card2: '10 of Spades'
'King of Diamonds' and '10 of Spades'
== : False
> : True
< : False
>= : True
<= : False
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。