[英]Is there a way to sort objects created through classes that is made up of both strings and integers in Python?
I have an assignment to create a deck of cards through the use of a class with methods that deal, shuffle, fan, order and checks if the deck is in order but I am having trouble creating the last one.我有一个任务是通过使用 class 来创建一副纸牌,该方法具有处理、洗牌、扇形、排序和检查纸牌是否有序的方法,但我无法创建最后一个。 The deck must be ordered by their values in each suit, and the suits ordered as Clubs, Diamonds, Hearts, and then Spades.
套牌必须按每套花色的值排序,花色依次为梅花、方块、红心和黑桃。 My code up to this point is found below:
到目前为止,我的代码如下:
import random
class Card():
def __init__(self, value, suit):
self.value = value
self.suit = suit
def show_card(self):
print(str(self.value)+ " of " + str(self.suit))
class Deck():
deck_of_cards = []
cards_in_play = []
draw_card = None
def __init__(self):
self.make_deck()
def make_deck(self):
for suit in ['Clubs', 'Diamonds', 'Hearts', 'Spades']:
for value in [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']:
self.deck_of_cards.append(Card(value,suit))
self.cards_in_play.append(Card(value, suit))
def shuffle(self):
self.shuffled_deck = random.shuffle(self.cards_in_play)
def fan(self):
for card in self.cards_in_play:
card.show_card()
def deal(self):
draw_card=self.cards_in_play.pop()
draw_card.show_card()
def order(self):
for suit in ['Club', 'Diamonds', 'Hearts', 'Spades']:
for value in [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']:
self.deck_of_cards.append(Card(value, suit))
self.cards_in_play.append(Card(value, suit))
Some code fixes before we go on:在我们 go 之前修复了一些代码:
suits
and values
list so that it can be used by all classes if needed.suits
和values
列表,以便在需要时可供所有班级使用。deck_of_cards
and cards_in_play
inside the __init__
function.__init__
function 中移动deck_of_cards
和cards_in_play
。 If you do not, this is called a "class attribute" and will make it so every class has that value if not initialized (likely something you do not intend).class Test:
a = 10
t1 = Test
t2 = Test
t1.a = 11
print(t2.a) # >>> 11
random.shuffle()
is a function that runs in place. random.shuffle()
是一个原地运行的 function。 In other words, it returns None
, but modifies the list given to it.None
,但修改了给它的列表。import random
l = ["a", "b", "c"]
print(random.shuffle(l)) # >>> None
print(l) # >>> [b, c, a]
def deal(self):
draw_card = self.cards_in_play.pop()
return draw_card
sort
and the __lt__
(detail below).sort
和__lt__
(详情如下)。import random
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']
class Card:
def __init__(self, value, suit):
self.suit = suit
self.value = value
def __lt__(self, other):
if suits.index(self.suit) > suits.index(other.suit):
return False
if values.index(self.value) > values.index(other.value):
return False
return True
def __repr__(self):
return f"{self.value} of {self.suit}"
class Deck:
def __init__(self):
self.deck_of_cards = []
self.cards_in_play = []
self.make_deck()
def make_deck(self):
for suit in suits:
for value in values:
self.deck_of_cards.append(Card(value,suit))
self.cards_in_play.append(Card(value, suit))
def shuffle(self):
random.shuffle(self.cards_in_play)
def fan(self):
for card in self.cards_in_play:
print(card)
def deal(self):
draw_card = self.cards_in_play.pop()
return draw_card
def order(self):
self.cards_in_play.sort()
def __repr__(self):
return repr(self.cards_in_play)
Utilizing the magic method __lt__
(less than), we can use the function sort
to automatically sort a class
.利用魔术方法
__lt__
(小于),我们可以使用 function sort
来自动排序class
。 To make the point more clear, notice the following:为了更清楚地说明这一点,请注意以下几点:
# Your new `order` function.
def order(self):
self.cards_in_play.sort()
# Implementing __lt__ now allows us to do the following comparison (which is what sort will use to sort your list of Card objects):
print(Card("Clubs", 2) > Card("Clubs", 3)) # True
# If you notice on docs, __ge__ (greater than), __eq__ (equal than), etc. can also be implemented to give you full flexibility.
Notice I also added the __repr__
function to both Deck
and Card
so that you can instead more simply do:请注意,我还将
__repr__
function 添加到Deck
和Card
中,以便您可以更简单地执行以下操作:
card = Card("Clubs", 2)
print(card) # >>> 2 of Clubs
Edit: @Discussion below.编辑:@Discussion 下面。
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']
class Card:
def __init__(self, value, suit):
self.suit = suit
self.value = value
def __lt__(self, other):
if suits.index(self.suit) > suits.index(other.suit):
return False
if values.index(self.value) > values.index(other.value):
return False
return True
def __eq__(self, other):
if self.suit == other.suit and self.value == other.value:
return True
else:
return False
def __repr__(self):
return f"{self.value} of {self.suit}"
With the new __eq__
method, we can use the ==
sign between classes.使用新的
__eq__
方法,我们可以在类之间使用==
符号。
c1 = Card(2, "Clubs")
c2 = Card(2, "Diamonds")
c3 = Card(2, "Diamonds")
print(c1 == c2) # False
print(c1 > c2) # False
print(c1 < c2) # True
print(c2 == c3) # True
This allows us to compare the Card
s with ease.这使我们可以轻松地比较
Card
。
You can initialize your Card class as follows:您可以按如下方式初始化您的卡 class:
values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King', 'Ace']
suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
class Card:
def __init__(self, value, suit):
self.suit = suit
self.value = value
#if value order matters in first place
self.rank = 4*values.index(self.value) + suits.index(self.suit)
#else
self.rank = 13*suits.index(self.suit) + values.index(self.value)
and create the check function as follows:并创建检查 function 如下:
class Deck:
def check(self):
rank_before = self.cards_in_play[0].rank
for card in self.cards_in_play[1:]:
rank = card.rank
if rank > rank_before:
rank_before = rank
else:
return False
return True
The canonical way to handle this is to realize that you have two identities for the card: its play value and its display value.处理这个问题的规范方法是意识到你有两个卡片的身份:它的播放值和它的显示值。 You need a simple cognate to the
__repr__
function.您需要一个简单的
__repr__
function 同源。
Very simply, value value
with a simple rank integer, card_rank
, 0-12.非常简单,使用简单等级 integer、
card_rank
、0-12 的value
。 The display value, what you print any time a human refers to it, is handled with a trivial translation list:显示值,即您在人类引用它时打印的内容,由一个简单的翻译列表处理:
print_value = (
'2', '3', '4', '5', '6', '7', '8', '9', '10',
'Jack', 'Queen', 'King', 'Ace'
)
Whenever you need to output a value, you simply use print_value[card_rank]
.每当您需要 output 一个值时,您只需使用
print_value[card_rank]
。 Put this into the __repr__
function of your Card
class.将此放入您的
Card
class 的__repr__
function 中。
With this partitioning of functionality, sorting by card_rank
solves your problem without further ado.通过这种功能划分,按
card_rank
排序可以轻松解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.