簡體   English   中英

用數字和字母對列表進行排序

[英]Sorting a list with both numbers and letters

我是一名一年級的 A-Level 學生,我正在嘗試對下面的列表進行排序,它代表了紙牌游戲 Rummy 中的一手牌:

hand = [(1, '-', '3', 'Spades'), (2, '-', '8', 'Clubs'), (3, '-', '10', 'Hearts'), (4, '-', 'Ace', 'Spades'), (5, '-', '7', 'Clubs'), (6, '-', 'Queen', 'Diamonds'), (7, '-', '10', 'Spades')]

我希望它按字母順序排序(梅花、梅花、方塊、紅心、黑桃、黑桃、黑桃),如果花色相同,則價值最低的牌(Ace 最低,King 最高)出現第一的。 排序后, index[0]值(在程序的其他部分中選擇一張卡時僅為每張卡提供參考編號)應該基本上重新分配,以便它們再次按從 1 到 7 的順序讀取。我想要它輸出如下:

[(1, '-', '7', 'Clubs'), (2, '-', '8', 'Clubs'), (3, '-', 'Queen', 'Diamonds'), (4, '-', '10', 'Hearts'), (5, '-', 'Ace', 'Spades'), (6, '-', '3', 'Spades'), (7, '-', '10', 'Spades')]

我想過嘗試做這樣的事情:

suit_hand = (hand[0][4], hand[1][4], hand[2][4], hand[3][4], hand[4][4], hand[5][4], hand[6][4])
arr = sorted(suit_hand)

然后對卡值使用標准排序算法,可能是插入排序,但我不太確定如何執行它。

任何幫助將不勝感激,謝謝。

您可以使用每張卡片的值之間的映射 ( '2': 2, ... 'Ace': 14 ) 來簡化比較:

value_rank = {
    **{'Jack': 11, 'Queen': 12, 'King': 13, 'Ace': 14},
    **{str(i): i for i in range(2, 11)}}

sorted(hand, key=lambda c: (c[3], -value_rank[c[2]]))
# out:
[(2, '-', '8', 'Clubs'),
 (5, '-', '7', 'Clubs'),
 (6, '-', 'Queen', 'Diamonds'),
 (3, '-', '10', 'Hearts'),
 (4, '-', 'Ace', 'Spades'),
 (7, '-', '10', 'Spades'),
 (1, '-', '3', 'Spades')]

哦,重新分配卡ID:

>>> [(i,) + c[1:] for i, c in enumerate(sorted(hand, key=lambda c: (c[3], -value_rank[c[2]])))]
[(0, '-', '8', 'Clubs'),
 (1, '-', '7', 'Clubs'),
 (2, '-', 'Queen', 'Diamonds'),
 (3, '-', '10', 'Hearts'),
 (4, '-', 'Ace', 'Spades'),
 (5, '-', '10', 'Spades'),
 (6, '-', '3', 'Spades')]

但是請注意,如果您花一些時間定義card class (帶有一些total_ordering的簡單namedtuple ),您將獲得更多可用的代碼:

@total_ordering
class card(namedtuple('Card', 'cid dash value suit')):
    def __eq__(self, other):
        return (self.suit, self.value) == (o.suit, o.value)
    
    def __lt__(self, o):
        return (self.suit, -value_rank[self.value]) < (o.suit, -value_rank[o.value])
    
    def with_id(self, cid):
        return card(cid, self.dash, self.value, self.suit)

hand = [card(*c) for c in hand]
[c.with_id(i) for i, c in enumerate(sorted(hand))]
# out:
[card(cid=0, dash='-', value='8', suit='Clubs'),
 card(cid=1, dash='-', value='7', suit='Clubs'),
 card(cid=2, dash='-', value='Queen', suit='Diamonds'),
 card(cid=3, dash='-', value='10', suit='Hearts'),
 card(cid=4, dash='-', value='Ace', suit='Spades'),
 card(cid=5, dash='-', value='10', suit='Spades'),
 card(cid=6, dash='-', value='3', suit='Spades')]

嘗試這個:

hand = [(1, '-', '3', 'Spades'), (2, '-', '8', 'Clubs'), (3, '-', '10', 'Hearts'), (4, '-', 'Ace', 'Spades'),
        (5, '-', '7', 'Clubs'), (6, '-', 'Queen', 'Diamonds'), (7, '-', '10', 'Spades')]
print(sorted(hand, key=lambda x: x[3]))

Output

[(2, '-', '8', 'Clubs'), (5, '-', '7', 'Clubs'), (6, '-', 'Queen', 'Diamonds'), (3, '-', '10', 'Hearts'), (1, '-', '3', 'Spades'), (4, '-', 'Ace', 'Spades'), (7, '-', '10', 'Spades')]

暫無
暫無

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

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