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