繁体   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