本文目录导读:

- 方法一:使用 random.shuffle(最简单)
- 方法二:实现 Fisher-Yates 洗牌算法
- 方法三:使用 random.sample
- 方法四:完整的扑克牌游戏案例
- 方法五:带验证的洗牌测试
- 方法六:加密安全的随机洗牌
- 推荐用法
我来介绍几种实现随机洗牌(Shuffle)的 Python 方法:
使用 random.shuffle(最简单)
import random
def shuffle_with_random(deck):
"""使用random.shuffle直接洗牌"""
deck = deck.copy() # 创建副本,避免修改原列表
random.shuffle(deck)
return deck
# 示例
cards = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
suits = ['♠', '♥', '♣', '♦']
# 创建一副完整的扑克牌
deck = [f'{card}{suit}' for suit in suits for card in cards]
print("原始牌序:", deck[:5])
shuffled_deck = shuffle_with_random(deck)
print("洗牌后:", shuffled_deck[:5])
实现 Fisher-Yates 洗牌算法
import random
def fisher_yates_shuffle(deck):
"""手动实现 Fisher-Yates 洗牌算法"""
deck = deck.copy()
n = len(deck)
for i in range(n-1, 0, -1):
# 从 0 到 i 中随机选择一个位置
j = random.randint(0, i)
# 交换位置 i 和 j 的元素
deck[i], deck[j] = deck[j], deck[i]
return deck
# 示例
deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("原始牌序:", deck)
print("Fisher-Yates洗牌:", fisher_yates_shuffle(deck))
使用 random.sample
import random
def shuffle_with_sample(deck):
"""使用random.sample实现洗牌"""
return random.sample(deck, len(deck))
# 示例
deck = list(range(1, 53)) # 52张牌
shuffled = shuffle_with_sample(deck)
print("洗牌结果(前10张):", shuffled[:10])
完整的扑克牌游戏案例
import random
class PokerDeck:
"""扑克牌类"""
def __init__(self):
self.suits = ['♠', '♥', '♣', '♦']
self.ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.deck = []
self.create_deck()
def create_deck(self):
"""创建新牌堆"""
self.deck = [f'{rank}{suit}' for suit in self.suits for rank in self.ranks]
def shuffle(self):
"""洗牌"""
random.shuffle(self.deck)
print("牌已洗好!")
def fisher_yates_shuffle(self):
"""使用Fisher-Yates算法洗牌"""
n = len(self.deck)
for i in range(n-1, 0, -1):
j = random.randint(0, i)
self.deck[i], self.deck[j] = self.deck[j], self.deck[i]
def deal_card(self):
"""发一张牌"""
if self.deck:
return self.deck.pop()
else:
return None
def deal_hand(self, num_cards):
"""发一手牌"""
hand = []
for _ in range(num_cards):
card = self.deal_card()
if card:
hand.append(card)
return hand
def show_deck(self):
"""显示牌堆"""
print(f"当前牌堆 ({len(self.deck)}张):")
for i, card in enumerate(self.deck, 1):
print(f"{card:4}", end=' ')
if i % 13 == 0:
print()
print()
# 使用示例
print("=== 扑克牌洗牌演示 ===")
deck = PokerDeck()
print("创建新牌堆:")
deck.show_deck()
print("洗牌后:")
deck.shuffle()
deck.show_deck()
print("发5张牌:")
hand = deck.deal_hand(5)
print("手牌:", hand)
print(f"剩余牌数: {len(deck.deck)}")
带验证的洗牌测试
import random
from collections import Counter
def test_shuffle_quality():
"""测试洗牌质量"""
original_deck = list(range(1, 53))
def shuffle_test(shuffle_func, iterations=1000):
"""多次洗牌测试"""
position_counts = Counter()
for _ in range(iterations):
deck = shuffle_func(original_deck.copy())
# 记录每张牌第一次出现的位置
for pos, card in enumerate(deck):
if card == 1: # 以第一张牌为例
position_counts[pos] += 1
break
return position_counts
# 使用random.shuffle测试
pos_counts = shuffle_test(random.shuffle)
print("洗牌1000次后,第一张牌出现在各位置的概率:")
for pos in range(0, 52, 5): # 每5个位置显示一次
probability = pos_counts.get(pos, 0) / 1000
print(f"位置 {pos:2d}: {probability:.2%}")
# 执行测试
test_shuffle_quality()
加密安全的随机洗牌
import secrets
import random
def cryptographically_secure_shuffle(deck):
"""使用secrets模块实现加密安全的洗牌"""
deck = deck.copy()
n = len(deck)
for i in range(n-1, 0, -1):
# secrets.randbelow 提供加密安全的随机数
j = secrets.randbelow(i + 1)
deck[i], deck[j] = deck[j], deck[i]
return deck
# 适用于需要高安全性的场景
deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
secure_shuffled = cryptographically_secure_shuffle(deck)
print("加密安全洗牌:", secure_shuffled)
推荐用法
# 最常用、最简单的洗牌方法 import random my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] random.shuffle(my_list) # 直接修改原列表 print(my_list) # 或者创建新列表 my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] new_list = random.sample(my_list, len(my_list)) # 返回新列表 print(new_list)
选择建议:
- 日常使用:
random.shuffle()最简单 - 需要原列表不变:
random.sample() - 了解原理:Fisher-Yates 算法
- 高安全性:使用
secrets模块