为什么sort()函数不能正确处理此列表中的整数



我正在尝试创建一副牌,洗牌,然后重新排序。

问题是,当我在混洗后对它进行排序时,列表最终是这样的:[10,11,12,13,8,9]

例如,我用了一个较小的甲板。有了完整的甲板,列表仍然结束:[10,11,12,13,1,2,…]

为什么列表没有正确排序?

这是我的代码:

import random
# Initialize Deck
deck = []
suits = ['Club', 'Spade', 'Heart', 'Diamond']
for i in range(8, 14):
for s in range(4):
deck.append([str(i), suits[s]])
# Format numbers into card face
for i in range(len(deck)):
if deck[i][0] == "1":
deck[i][0] = "Ace"
elif deck[i][0] == "11":
deck[i][0] = "J"
elif deck[i][0] == "12":
deck[i][0] = "Q"
elif deck[i][0] == "13":
deck[i][0] = "K"
print("Initial deck", deck)
print()
# Shuffle Deck
random.shuffle(deck)
print("Shuffle function:", deck)
# Turn face back to number for sorting
for i in range(len(deck)):
if deck[i][0] == "Ace":
deck[i][0] = "1"
elif deck[i][0] == "J":
deck[i][0] = "11"
elif deck[i][0] == "Q":
deck[i][0] = "12"
elif deck[i][0] == "K":
deck[i][0] = "13"

deck.sort()
print("Sort function: ", deck)

输出:

Initial deck: [['8', 'Club'], ['8', 'Spade'], ['8', 'Heart'], ['8', 'Diamond'], ['9', 'Club'], ['9', 'Spade'], ['9', 'Heart'], ['9', 'Diamond'], ['10', 'Club'], ['10', 'Spade'], ['10', 'Heart'], ['10', 'Diamond'], ['J', 'Club'], ['J', 'Spade'], ['J', 'Heart'], ['J', 'Diamond'], ['Q', 'Club'], ['Q', 'Spade'], ['Q', 'Heart'], ['Q', 'Diamond'], ['K', 'Club'], ['K', 'Spade'], ['K', 'Heart'], ['K', 'Diamond']]
Shuffle function: [['J', 'Heart'], ['8', 'Club'], ['Q', 'Spade'], ['9', 'Diamond'], ['9', 'Heart'], ['10', 'Diamond'], ['K', 'Heart'], ['K', 'Spade'], ['10', 'Heart'], ['9', 'Club'], ['8', 'Heart'], ['K', 'Club'], ['8', 'Diamond'], ['Q', 'Diamond'], ['9', 'Spade'], ['Q', 'Heart'], ['10', 'Spade'], ['K', 'Diamond'], ['J', 'Diamond'], ['Q', 'Club'], ['10', 'Club'], ['8', 'Spade'], ['J', 'Spade'], ['J', 'Club']]
Sort function:  [['10', 'Club'], ['10', 'Diamond'], ['10', 'Heart'], ['10', 'Spade'], ['11', 'Club'], ['11', 'Diamond'], ['11', 'Heart'], ['11', 'Spade'], ['12', 'Club'], ['12', 'Diamond'], ['12', 'Heart'], ['12', 'Spade'], ['13', 'Club'], ['13', 'Diamond'], ['13', 'Heart'], ['13', 'Spade'], ['8', 'Club'], ['8', 'Diamond'], ['8', 'Heart'], ['8', 'Spade'], ['9', 'Club'], ['9', 'Diamond'], ['9', 'Heart'], ['9', 'Spade']]

这是因为列表中的值是列表,而这些列表包含字符串。试试这样的东西:

import random
# Initialize Deck
deck = []
suits = ['Club', 'Spade', 'Heart', 'Diamond']
for i in range(8, 14):
for s in range(4):
deck.append([i, suits[s]])
# Format numbers into card face
for i in range(len(deck)):
if deck[i][0] == 1:
deck[i][0] = "Ace"
elif deck[i][0] == 11:
deck[i][0] = "J"
elif deck[i][0] == 12:
deck[i][0] = "Q"
elif deck[i][0] == 13:
deck[i][0] = "K"
print("Initial deck", deck)
print()
# Shuffle Deck
random.shuffle(deck)
print("Shuffle function:", deck)
# Turn face back to number for sorting
for i in deck:
if deck[i][0] == "Ace":
deck[i][0] = 1
elif deck[i][0] == "J":
deck[i][0] = 11
elif deck[i][0] == "Q":
deck[i][0] = 12
elif deck[i][0] == "K":
deck[i][0] = 13

deck.sort(key=lambda x:return x[0])
print("Sort function: ", deck)

您希望列组为int值(而不是其str版本(,以便对它们进行比较以进行排序。来回翻转它们进行打印/排序是一项不必要的工作;我建议用__repr__方法定义一个对象类,该方法可以按照您想要的方式对它们进行格式化。

import random

class Card:
def __init__(self, rank: int, suit: str):
self.rank = rank
self.suit = suit
def __repr__(self) -> str:
rank_names = {
1: "Ace",
11: "J",
12: "Q",
13: "K",
}
return f"[{rank_names.get(self.rank, self.rank)} {self.suit}]"

deck = [
Card(rank, suit) 
for rank in range(8, 14) 
for suit in ['Club', 'Spade', 'Heart', 'Diamond']
]
print("Initial deck", deck, "n")
random.shuffle(deck)
print("Shuffled deck:", deck, "n")
deck.sort(key=lambda card: (card.rank, card.suit))
print("Sorted deck:", deck)

打印:

Initial deck [[8 Club], [8 Spade], [8 Heart], [8 Diamond], [9 Club], [9 Spade], [9 Heart], [9 Diamond], [10 Club], [10 Spade], [10 Heart], [10 Diamond], [J Club], [J Spade], [J Heart], [J Diamond], [Q Club], [Q Spade], [Q Heart], [Q Diamond], [K Club], [K Spade], [K Heart], [K Diamond]]
Shuffled deck: [[K Heart], [10 Club], [9 Diamond], [8 Diamond], [10 Spade], [J Spade], [K Spade], [J Heart], [9 Spade], [10 Heart], [K Club], [10 Diamond], [Q Club], [K Diamond], [Q Spade], [J Diamond], [Q Diamond], [J Club], [9 Club], [8 Club], [9 Heart], [8 Heart], [Q Heart], [8 Spade]]
Sorted deck: [[8 Club], [8 Diamond], [8 Heart], [8 Spade], [9 Club], [9 Diamond], [9 Heart], [9 Spade], [10 Club], [10 Diamond], [10 Heart], [10 Spade], [J Club], [J Diamond], [J Heart], [J Spade], [Q Club], [Q Diamond], [Q Heart], [Q Spade], [K Club], [K Diamond], [K Heart], [K Spade]]

对于数值,应该使用整数而不是字符串。我还建议您将两个元素的内部列表替换为类似元组(更多的是风格选择(:

[(8, 'Club'), (8, 'Spade'), ...]

如果您坚持使用字符串,那么您可以在排序函数中添加key参数。它接受一个在比较之前映射对象的函数。在您的情况下:

deck.sort(key=lambda x: int(x[0]))

其获取列表的每个元素并将该元素的第一个成员转换为整数。

另一个建议是,使用字典而不是if-else来映射数字和卡面,就像这样:

# Dictionary instead of if/elif/else
number_to_face = {
"1": "Ace",
"11": "J",
"12": "Q",
"13": "K"
}

下面是一个完整的调整示例。

import random
# Initialize Deck
deck = []
suits = ['Club', 'Spade', 'Heart', 'Diamond']
for i in range(8, 14):
for s in range(4):
deck.append((str(i), suits[s]))
# Dictionary instead of if/elif/else
number_to_face = {
"1": "Ace",
"11": "J",
"12": "Q",
"13": "K"
}
# Reverse mapping of key -> value to value -> key
face_to_number = {v: k for k, v in number_to_face.items()}
# Use list comprehension to update list
def map_with(deck, mapping):
return [(mapping.get(k, k), v) for k, v in deck]
# Format numbers into card face
deck = map_with(deck, number_to_face)
print("Initial deck", deck)
print()
# Shuffle Deck
random.shuffle(deck)
print("Shuffle function:", deck)
print()
# Turn face back to number for sorting
# Use list comprehension to update list
deck = map_with(deck, face_to_number)

deck.sort(key=lambda x: int(x[0]))
print("Sort function: ", deck)

最新更新