如何在Python中生成不重复的52位0-12随机向量(模拟洗牌)
正确生成符合要求的随机向量(模拟扑克牌洗牌)
首先纠正两个关键误解:
- 你要的不是任意52位0-12的向量,而是每个数字0-12恰好出现4次的向量(对应一副扑克牌13个点数各4张),你之前的代码用
randint随机生成每个元素,大概率会出现数字次数不均的情况,这才是你“运行数小时没得到目标向量”的核心原因。 - 总排列数不是52!,而是多重排列数:
52! / (4!^13),这个数约为5.3×10^28,是个天文数字,所以即使生成几十亿次,重复的概率也几乎为0。
正确实现方法
直接模拟真实洗牌逻辑:先构建一个包含4个0、4个1……4个12的初始列表,再用Python内置的洗牌函数打乱顺序,这样每次得到的都是符合要求的随机向量,且几乎不会重复。
代码示例:
import random # 构建初始牌组:0-12每个数字出现4次 deck = [num for num in range(13) for _ in range(4)] # 原地打乱顺序(洗牌) random.shuffle(deck) # 此时deck就是你需要的52位向量 print(deck)
关于“避免生成重复向量”
由于总排列数极大,实际使用中random.shuffle生成重复向量的概率可以忽略不计。如果确实需要严格避免重复(比如做极端测试),可以用集合记录已生成的向量(列表不能直接存集合,转成元组即可):
import random generated_decks = set() def get_unique_deck(): while True: deck = [num for num in range(13) for _ in range(4)] random.shuffle(deck) deck_tuple = tuple(deck) if deck_tuple not in generated_decks: generated_decks.add(deck_tuple) return deck # 获取一个唯一的洗牌结果 unique_deck = get_unique_deck() print(unique_deck)
为什么你的原代码不行?
randint(0,12)是独立随机生成每个元素,会出现比如0出现5次、1出现3次的情况,完全不符合扑克牌的结构,这种方法生成合法向量(每个数字4次)的概率极低,相当于大海捞针,所以你运行很久也得不到目标结果。
内容的提问来源于stack exchange,提问作者Jonathan Brown
相关产品推荐
相关产品推荐

