简体   繁体   English

有没有办法对通过 Python 中由字符串和整数组成的类创建的对象进行排序?

[英]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 之前修复了一些代码:

  1. Universalize the suits and values list so that it can be used by all classes if needed.通用化suitsvalues列表,以便在需要时可供所有班级使用。
  2. Move deck_of_cards and cards_in_play inside the __init__ function.__init__ function 中移动deck_of_cardscards_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 都会具有该值(可能你不打算这样做)。
class Test:
    a = 10

t1 = Test
t2 = Test

t1.a = 11
print(t2.a) # >>> 11
  1. 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]
  1. Don't print things -- return them.不要打印东西——退回它们。 It will make your code not only clearer, but also more useful.它将使您的代码不仅更清晰,而且更有用。 If you want to print something that a function returns, just simply print the return.如果要打印 function 返回的内容,只需打印返回即可。
def deal(self):
    draw_card = self.cards_in_play.pop()
    return draw_card
  1. Familiarize yourself with 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 添加到DeckCard中,以便您可以更简单地执行以下操作:

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.

相关问题 对同时包含字符串和整数的列表进行排序 (Python) - Sort a list that contains both strings and integers (Python) 在python3中对包含字符串和整数的文件进行排序 - To sort a file which contains both strings and integers in python3 Python:如何使用字符串和整数的组合对数组进行排序 - Python: How to sort an Array with with a combination of Strings and Integers 有没有办法在由Python脚本创建的内存中保存一大串字符串,并将其提供给当前的bash shell? - Is there a way to hold a big list of strings in memory created from a Python script, and made available to the current bash shell? 使用 Python - 如何解析整数和字符串的 CSV 列表并通过插入语句添加到 SQL 表? - Using Python - How can I parse CSV list of both integers and strings and add to SQL table through Insert Statement? 函数,可调用对象以及如何在Python中创建它们 - Functions, Callable Objects, and how both are created in Python 如何比较具有字符串和整数的列? 蟒蛇熊猫 - How to compare columns with both strings and integers? Python Pandas 在Python中从文本文件中选择整数/字符串并对其进行排序 - Select and sort integers/strings from a text file in Python 对包含整数的字符串列表进行排序,同时忽略 python 中的空格 - Sort a list of strings that contain integers while ignoring white space in python 如何将嵌套列表字符串转换为整数,然后在python 3中对其进行排序? - How to convert nested list strings to integers then sort them in python 3?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM