簡體   English   中英

有沒有辦法對通過 Python 中由字符串和整數組成的類創建的對象進行排序?

[英]Is there a way to sort objects created through classes that is made up of both strings and integers in Python?

我有一個任務是通過使用 class 來創建一副紙牌,該方法具有處理、洗牌、扇形、排序和檢查紙牌是否有序的方法,但我無法創建最后一個。 套牌必須按每套花色的值排序,花色依次為梅花、方塊、紅心和黑桃。 到目前為止,我的代碼如下:

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))

在我們 go 之前修復了一些代碼:

  1. 通用化suitsvalues列表,以便在需要時可供所有班級使用。
  2. __init__ function 中移動deck_of_cardscards_in_play 如果你不這樣做,這被稱為 “類屬性” ,並且如果沒有初始化,每個 class 都會具有該值(可能你不打算這樣做)。
class Test:
    a = 10

t1 = Test
t2 = Test

t1.a = 11
print(t2.a) # >>> 11
  1. random.shuffle()是一個原地運行的 function。 換句話說,它返回None ,但修改了給它的列表。
import random

l = ["a", "b", "c"]
print(random.shuffle(l)) # >>> None
print(l) # >>> [b, c, a]
  1. 不要打印東西——退回它們。 它將使您的代碼不僅更清晰,而且更有用。 如果要打印 function 返回的內容,只需打印返回即可。
def deal(self):
    draw_card = self.cards_in_play.pop()
    return draw_card
  1. 熟悉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)

利用魔術方法__lt__ (小於),我們可以使用 function sort來自動排序class 為了更清楚地說明這一點,請注意以下幾點:

# 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.

請注意,我還將__repr__ function 添加到DeckCard中,以便您可以更簡單地執行以下操作:

card = Card("Clubs", 2)
print(card) # >>> 2 of Clubs

編輯:@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}"

使用新的__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

這使我們可以輕松地比較Card

您可以按如下方式初始化您的卡 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)

並創建檢查 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

處理這個問題的規范方法是意識到你有兩個卡片的身份:它的播放值和它的顯示值。 您需要一個簡單的__repr__ function 同源。

非常簡單,使用簡單等級 integer、 card_rank 、0-12 的value 顯示值,即您在人類引用它時打印的內容,由一個簡單的翻譯列表處理:

print_value = (
    '2', '3', '4', '5', '6', '7', '8', '9', '10',
    'Jack', 'Queen', 'King', 'Ace'
)

每當您需要 output 一個值時,您只需使用print_value[card_rank] 將此放入您的Card class 的__repr__ function 中。

通過這種功能划分,按card_rank排序可以輕松解決您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM