我有两个清单:
card_candidates = ['9D', '9S', '3S', '0D']
card_order = ['2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A']
我希望能够根据第二个列表顺序对第一个列表进行排序。所以排序后的card_candidates应如下所示:
sorted_candidates = ['3S', '9D', '9S', '0D']
'0'只是10的值,只是想让所有卡的长度相同。如果存在平局,例如“9D”和“9S”,则需要对字母进行排序。到目前为止,我刚刚做到了这一点:
sorted_candidates = []
for x, y in zip(card_candidates, card_order):
sorted_candidates.append([x[0] for x in card_candidates])
return sorted(sorted_candidates)
我知道这甚至不是正确的,我只是不知道该怎么做。
答案 0 :(得分:10)
生成将排序顺序字符映射到数字的字典,我们将按以下顺序排序:
sort_map = {c: i for i, c in enumerate(card_order)}
现在,您可以使用此映射对卡片进行排序,包括断开连接的第二个字母:
sorted_candidates = sorted(card_candidates,
key=lambda card: (sort_map[card[0]], card[1]))
sort键获取每张卡的第一个字符,并将其转换为sort_map
字典中的整数,然后通知sorted()
函数正确的排序顺序。如果是平局(卡值相等),卡片将按照俱乐部,钻石,心形和黑桃的顺序排序(假设您使用C
和H
来表示俱乐部和心脏)。
创建前映射保持排序在O(NlogN)时间复杂度内;您可以对card_order.index(card[0])
执行相同操作,但随后为每个已排序的元素调用list.index()
调用,并且list.index
需要扫描列表,生成O (KNlogN)sort(其中K是card_order
列表的长度)。
演示:
>>> card_candidates = ['9D', '9S', '3S', '0D']
>>> card_order = ['2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A']
>>> sort_map = {c: i for i, c in enumerate(card_order)}
>>> sorted(card_candidates, key=lambda card: (sort_map[card[0]], card[1]))
['3S', '9D', '9S', '0D']
>>> sorted(['9D', '9S', '9C', '9H'], key=lambda card: (sort_map[card[0]], card[1]))
['9C', '9D', '9H', '9S']
答案 1 :(得分:2)
您不一定需要任何其他数据结构,card_order
列表完全足以使用这个简单的单行排序您的卡片:
card_candidates = ['9D', '9S', '3S', '0D']
card_order = ['2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A']
sorted_cards = sorted(card_candidates, key=lambda c: (card_order.index(c[0]), c[1]))
print(list(sorted_cards))
输出:
['3S', '9D', '9S', '0D']
See this code running on ideone.com
请注意,每次对每张卡片进行排序时,此方法会扫描card_order
列表中的每张卡片。如果您只是在游戏开始时或甚至每隔几秒钟对一副普通卡片进行排序,这就没有问题。但是,如果您的代码大部分时间都在排序大量的卡或排序卡,您可能希望Martijn Pieters更喜欢解决方案,它将card_order
列表转换为可以更快扫描的字典。