oeasy Python 116 用列表乱序shuffle来洗牌抓拍玩升级拖拉机

  • 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。

用列表乱序shuffle来洗牌抓拍玩升级拖拉机

回忆
  • 上次我们了解了
  1. 定点插入 insert
  • 相对原来的 追加append
  1. 定点删除 pop
  • 相对原来的 按值删除 remove
  • 排好序 之后 可以​打乱​顺序吗?
乱序
  • 好像来自我们熟悉的包
  • random
random.shuffle
复制代码
import random
nl = list(range(4))
random.shuffle(nl)
nl
random.shuffle(nl)
nl
  • 效果
  • shuffle 之前 见过吗?
回忆
  • 以前用的是
  • random.randint
  • 得到 随机整数
  • random.choice
  • 选择 一个 列表项
  • shuflle怎么理解?
help
复制代码
import random
help(random.shuffle)
  • 在原地
  • 打乱列表的次序
  • 次序​乱​了 有啥好的吗?
shuffle
  • 随机安排角色
  • 随机抓牌
  • shuffle 本身就是洗牌的意思
洗牌
  • 一副牌54张
  • 每张牌一个编号
  • 把牌洗开
洗牌
复制代码
import random 
poker_list = list(range(54))
random.shuffle(poker_list)
print(poker_list)
  • 牌洗好了
  • 不过洗的是牌的序号
  • 扑克字符
扑克字符
  • 要先 把 扑克牌 换成 字符
  • unicode中包含扑克的字符
  • 把 相关范围 都 遍历一遍
遍历范围
复制代码
import random
for n in range(0x1f0a0, 0x1f0ff):
	print(chr(n), end = " ")
  • 输出结果
  • 为什么JQK之外还有C?
花色来历
  • 唐宋的叶子戏
  • 传入波斯、阿拉伯
  • 经过意大利、德国
  • 骑士牌 (Cavalier/Knight)
  • 是欧洲传统扑克牌的一部分
  • 现在是英法花色 成为主流
  • 在此基础上 构成了 美式扑克
  • 这些排面有什么说法?
排面
  • 人物也完成了 本地化
  • 四大天王(king) 都来自英法
  • 人物有什么含义
人物含义

|----|-----|--------|------------------|
| 牌面 | 花色 | 对应角色 | 核心身份 |
| K | 红桃♥ | 查理曼大帝 | 法兰克国王,西欧统一者 |
| | 黑桃♠ | 大卫王 | 以色列国王,《圣经》人物 |
| | 梅花♣ | 亚历山大大帝 | 马其顿国王,欧亚非征服者 |
| | 方块♦ | 凯撒大帝 | 罗马独裁官,罗马帝国奠基者 |
| Q | 红桃♥ | 朱迪思 | 犹太女英雄,《圣经》外典人物 |
| | 黑桃♠ | 雅典娜 | 希腊神话智慧与战争女神 |
| | 梅花♣ | 阿金尼 | 传说爱神(原型关联伊丽莎白一世) |
| | 方块♦ | 拉结 | 《圣经》中雅各的妻子 |
| J | 红桃♥ | 拉海尔 | 法国骑士,圣女贞德追随者 |
| | 黑桃♠ | 奥吉尔 | 查理曼大帝的圣骑士 |
| | 梅花♣ | 兰斯洛特 | 亚瑟王圆桌骑士,圣杯守护者 |
| | 方块♦ | 赫克托尔 | 特洛伊王子,神话勇士 |

  • King > Queen > Jack(侍从)
  • 为什么是 黑红梅方 四个花色?
花色
  • 4组花色
  • 代表四季
  • 为什么是54张?
54张牌
  • 52张正牌正好代表
  • 一年中有52个星期
  • 为什么 黑桃A 那么不同?
印花税
  • 1712年
  • 英国开始征收
  • 印花税
  • stamp duty
  • 每一副牌必须有纳税的痕迹才能离开工厂
  • 执行人 给
  • 缴税纸牌的第一张
  • 也就是黑桃A
  • 盖上墨水戳
  • 牌面 比K还大
  • 想要 洗​真正的牌​
  • 可以吗?
提问
代码
复制代码
# 生成仅含 Unicode 字符的 54 张扑克牌列表
deck = []

# 花色偏移:0=黑桃 1=红桃 2=梅花 3=方块
suits_offset = [0, 1, 2, 3]
# 牌面偏移:对应 A-K,跳过无效的 12、15
ranks_offset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]

# 生成 4花色×13张牌,同时记录草花K的编码
club_k_code = None
for suit in suits_offset:
    for rank in ranks_offset:
        code = 0x1F0A0 + suit * 16 + rank
        deck.append(chr(code))
        # 捕获草花K的编码(花色偏移2,牌面偏移14)
        if suit == 2 and rank == 14:
            club_k_code = code

# 小王编码 = 草花K编码 + 1
joker_small_code = 0x1F0DF
# 大王编码 = 小王编码 + 12(按 Unicode 实际排版逻辑)
joker_big_code = 0x1F0CF

# 添加大小王
deck.append(chr(joker_small_code))
deck.append(chr(joker_big_code))

# 验证长度和输出
print(f"牌组长度: {len(deck)}")
print(f"草花K编码: 0x{club_k_code:X}, 字符: {chr(club_k_code)}")
print(f"小王编码: 0x{joker_small_code:X}, 字符: {chr(joker_small_code)}")
print(f"大王编码: 0x{joker_big_code:X}, 字符: {chr(joker_big_code)}")
print("\n完整牌组:")
print(" ".join(deck))
print(len(deck))
调整颜色
效果
复制代码
BLACK_FG = "\033[30m"   # 黑色前景
RED_FG = "\033[31m"     # 红色前景
WHITE_BG = "\033[47m"   # 白色背景
RESET = "\033[0m"       # 重置所有样式

deck = []
colored_deck = []

# 花色偏移: 0=黑桃 1=红桃 2=方块 3=梅花,绑定对应前景色
suits = {
    0: BLACK_FG,
    1: RED_FG,
    2: RED_FG,
    3: BLACK_FG
}
# 有效牌面偏移 (A-K)
ranks_offset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]

# 生成 4花色×13张牌,记录草花K编码
club_k_code = None
for suit_offset, fg_color in suits.items():
    for rank in ranks_offset:
        code = 0x1F0A0 + suit_offset * 16 + rank
        card_char = chr(code)
        deck.append(card_char)
        # 拼接:前景色+白色背景+字符+重置
        colored_card = f"{fg_color}{WHITE_BG}{card_char}{RESET}"
        colored_deck.append(colored_card)
        # 捕获草花K编码
        if suit_offset == 2 and rank == 14:
            club_k_code = code

# 处理大小王
joker_small_code = 0x1F0DF  # 小王:草花K+1
joker_big_code = 0x1F0CF           # 大王标准编码

# 小王:白背景+黑前景;大王:保持原样
joker_small = f"{BLACK_FG}{WHITE_BG}{chr(joker_small_code)}{RESET}"
joker_big = chr(joker_big_code)

# 加入两个列表
deck.append(chr(joker_small_code))
deck.append(chr(joker_big_code))
colored_deck.append(joker_small)
colored_deck.append(joker_big)

# 验证与输出
for card in colored_deck:
    print(card, end=" ")
洗牌
  • 洗牌
复制代码
import random
BLACK_FG = "\033[30m"   # 黑色前景
RED_FG = "\033[31m"     # 红色前景
WHITE_BG = "\033[47m"   # 白色背景
RESET = "\033[0m"       # 重置所有样式

deck = []
colored_deck = []

# 花色偏移: 0=黑桃 1=红桃 2=方块 3=梅花,绑定对应前景色
suits = {
    0: BLACK_FG,
    1: RED_FG,
    2: RED_FG,
    3: BLACK_FG
}
# 有效牌面偏移 (A-K)
ranks_offset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]

# 生成 4花色×13张牌,记录草花K编码
club_k_code = None
for suit_offset, fg_color in suits.items():
    for rank in ranks_offset:
        code = 0x1F0A0 + suit_offset * 16 + rank
        card_char = chr(code)
        deck.append(card_char)
        # 拼接:前景色+白色背景+字符+重置
        colored_card = f"{fg_color}{WHITE_BG}{card_char}{RESET}"
        colored_deck.append(colored_card)
        # 捕获草花K编码
        if suit_offset == 2 and rank == 14:
            club_k_code = code

# 处理大小王
joker_small_code = 0x1F0DF  # 小王:草花K+1
joker_big_code = 0x1F0CF           # 大王标准编码

# 小王:白背景+黑前景;大王:保持原样
joker_small = f"{BLACK_FG}{WHITE_BG}{chr(joker_small_code)}{RESET}"
joker_big = chr(joker_big_code)

# 加入两个列表
deck.append(chr(joker_small_code))
deck.append(chr(joker_big_code))
colored_deck.append(joker_small)
colored_deck.append(joker_big)

random.shuffle(colored_deck)

# 验证与输出
for card in colored_deck:
    print(card, end=" ")
洗牌结果
  • 扑克有啥玩法呢?
升级
  • 4个人
  • 每人抓12轮
  • 总共抓48张
  • 还剩6张
  • 扣为底牌
  • 底牌归当前轮的庄家
抓牌
复制代码
import random
BLACK_FG = "\033[30m"   # 黑色前景
RED_FG = "\033[31m"     # 红色前景
WHITE_BG = "\033[47m"   # 白色背景
RESET = "\033[0m"       # 重置所有样式

deck = []
colored_deck = []

# 花色偏移: 0=黑桃 1=红桃 2=方块 3=梅花,绑定对应前景色
suits = {
    0: BLACK_FG,
    1: RED_FG,
    2: RED_FG,
    3: BLACK_FG
}
# 有效牌面偏移 (A-K)
ranks_offset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]

# 生成 4花色×13张牌,记录草花K编码
club_k_code = None
for suit_offset, fg_color in suits.items():
    for rank in ranks_offset:
        code = 0x1F0A0 + suit_offset * 16 + rank
        card_char = chr(code)
        deck.append(card_char)
        # 拼接:前景色+白色背景+字符+重置
        colored_card = f"{fg_color}{WHITE_BG}{card_char}{RESET}"
        colored_deck.append(colored_card)
        # 捕获草花K编码
        if suit_offset == 2 and rank == 14:
            club_k_code = code

# 处理大小王
joker_small_code = 0x1F0DF  # 小王:草花K+1
joker_big_code = 0x1F0CF           # 大王标准编码

# 小王:白背景+黑前景;大王:保持原样
joker_small = f"{BLACK_FG}{WHITE_BG}{chr(joker_small_code)}{RESET}"
joker_big = chr(joker_big_code)

# 加入两个列表
deck.append(chr(joker_small_code))
deck.append(chr(joker_big_code))
colored_deck.append(joker_small)
colored_deck.append(joker_big)

random.shuffle(colored_deck)

dong = colored_deck[0:48:4]
nan = colored_deck[1:48:4]
xi = colored_deck[2:48:4]
bei = colored_deck[3:48:4]
di = colored_deck[-6:]
print("\n东:" + " ".join(dong))
print("南:" + " ".join(nan))
print("西:" + " ".join(xi))
print("北:" + " ".join(bei))
print("底:" + " ".join(di))
  • 抓牌結果
  • 牌抓到手里 还是要理一理的
最終代碼
复制代码
import random
BLACK_FG = "\033[30m"   # 黑色前景
RED_FG = "\033[31m"     # 红色前景
WHITE_BG = "\033[47m"   # 白色背景
RESET = "\033[0m"       # 重置所有样式

deck = []
colored_deck = []

# 花色偏移: 0=黑桃 1=红桃 2=方块 3=梅花,绑定对应前景色
suits = {
    0: BLACK_FG,
    1: RED_FG,
    2: RED_FG,
    3: BLACK_FG
}
# 有效牌面偏移 (A-K)
ranks_offset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14]

# 生成 4花色×13张牌,记录草花K编码
club_k_code = None
for suit_offset, fg_color in suits.items():
    for rank in ranks_offset:
        code = 0x1F0A0 + suit_offset * 16 + rank
        card_char = chr(code)
        deck.append(card_char)
        # 拼接:前景色+白色背景+字符+重置
        colored_card = f"{fg_color}{WHITE_BG}{card_char}{RESET}"
        colored_deck.append(colored_card)
        # 捕获草花K编码
        if suit_offset == 2 and rank == 14:
            club_k_code = code

# 处理大小王
joker_small_code = 0x1F0DF  # 小王:草花K+1
joker_big_code = 0x1F0CF           # 大王标准编码

# 小王:白背景+黑前景;大王:保持原样
joker_small = f"{BLACK_FG}{WHITE_BG}{chr(joker_small_code)}{RESET}"
joker_big = chr(joker_big_code)

# 加入两个列表
deck.append(chr(joker_small_code))
deck.append(chr(joker_big_code))
colored_deck.append(joker_small)
colored_deck.append(joker_big)

random.shuffle(colored_deck)

dong = colored_deck[0:48:4]
nan = colored_deck[1:48:4]
xi = colored_deck[2:48:4]
bei = colored_deck[3:48:4]
di = colored_deck[-6:]
dong.sort()
nan.sort()
xi.sort()
bei.sort()

print("\n东:" + " ".join(dong))
print("南:" + " ".join(nan))
print("西:" + " ".join(xi))
print("北:" + " ".join(bei))
print("底:" + " ".join(di))
  • 这样同样花色就被理顺了
列表函數总结
  • 列表所有方法
  • 再复习一遍

|----------|---------|----------------------|
| 功能类别 | 方法名称 | 操作说明(简化) |
| 🔹 元素添加 | append | 列表末尾添加单个元素(任意类型) |
| | extend | 末尾批量添加可迭代对象元素(展开) |
| | insert | 指定索引位置插入单个元素,后续元素后移 |
| 🔹 元素删除 | remove | 查找并删除第一个匹配 value 的元素 |
| | pop | 删除并返回指定索引元素,默认删最后一个 |
| | clear | 清空列表所有元素,保留列表对象 |
| 🔹 查找与统计 | index | 查找并返回第一个匹配 value 的索引 |
| | count | 统计 value 元素出现的次数 |
| 🔹 排序与反转 | sort | 原地排序,支持自定义规则 |
| | reverse | 原地反转列表元素顺序 |
| 🔹 复制操作 | copy | 返回列表的浅拷贝新列表 |

  • 需要有所突破了
总结
  • 这次 我们了解了 ​无序​
  • 排序 可以 让列表 ​有序​
  • 随机 可以 让列表 ​无序​
  • 无序有序都用
  • 有序带来理性的方便
  • 无序带来混沌的快乐
  • 洗牌、码牌、抓牌、看牌
  • 理牌 可以让手里的牌
  • 有适合出牌的次序
  • 目前 列表 都是 一维的
  • 可以 升到 有​更高维度​ 吗? 🤔
  • 下次再说 👋

  • 本文来自 oeasy Python 系统教程。

  • 想完整、扎实学 Python,

  • 搜索 oeasy 即可。

相关推荐
晚秋大魔王1 小时前
Trilium Note 服务器部署
运维·服务器
A懿轩A2 小时前
【Java 基础编程】Java 枚举与注解从零到一:Enum 用法 + 常用注解 + 自定义注解实战
java·开发语言·python
独自破碎E2 小时前
Windows 环境下 OpenClaw 的安装与千问大模型配置
windows
RisunJan2 小时前
Linux命令-lvremove(删除指定LVM逻辑卷)
linux·运维·服务器
SmartBrain2 小时前
FastAPI实战(第二部分):用户注册接口开发详解
数据库·人工智能·python·fastapi
开发者导航2 小时前
【开发者导航】多功能生成模型开发工具:Diffusers 详细介绍
人工智能·python·学习·macos·信息可视化
ん贤2 小时前
Scrapy 嵌入 FastAPI 的坑:Asyncio/Twisted 桥接 + 代理池设计
python·scrapy·fastapi
岱宗夫up2 小时前
从代码模式到智能模式:AI时代的设计模式进化论
开发语言·python·深度学习·神经网络·自然语言处理·知识图谱
xzjiang_3652 小时前
Jupyter 运行经验3:读入和显示一张图片
ide·python·jupyter