任务速览:遇到一段陌生 Python,先让 GitHub Copilot Chat 解释,再用纸笔追踪变量。本文适合认识变量、列表和循环的初学者,交付一份“输入约定、逐步解释、测试预期”笔记,不运行代码,也不修改仓库。
准备与费用:准备可登录的 GitHub 账号和浏览器。Copilot Free提供受限免费额度;已有组织授权的账号按组织方案使用,具体可用量以账号页面为准。还须符合地区与服务限制。本文不需要安装编辑器、Python 或扩展,也不用购买订阅。入口不可用或额度耗尽时,先完成下面的人工推导。
第一步:限定到一段没有外部依赖的代码
按官方网页操作说明打开 Copilot Chat,使用普通聊天,不添加仓库上下文。粘贴这段原创教学代码。输入约定为字符串列表;示例只用英文字母和空格组成的标签。
def normalize_labels(values):
result = []
for value in values:
label = value.strip().lower()
if label and label not in result:
result.append(label)
return result
它只处理传入的列表,没有文件、网络或数据库操作。读陌生代码时也先寻找这些外部动作;出现不认识的函数调用,补齐其定义再分析,不能凭函数名猜行为。
第二步:让解释落到每次循环
在代码后追加以下提示并发送:
只阅读这段Python 3代码,不运行、不改写、不调用工具, 不创建文件、提交或拉取请求。 先说明输入约定、返回值、是否修改原列表。 再解释每行的作用,不用“智能清洗”等笼统说法。 对输入[" B ", "a", "b", " "],逐轮列出: value、strip后的值、lower后的label、是否追加、result。 最后指出空列表、内部空格、非字符串元素的行为。 区分代码确定的行为和调用者可能想要的行为。 所有结果标为推导,不声称运行过。
若回复转向安装软件、执行命令或交给编程代理,停止该流程,重申只要文本解释。不要为了“验证”而把陌生项目接进来。
第三步:亲手核对状态变化
按 Python 文档,strip() 去掉两端空白,lower() 返回小写形式;这两个操作不会去掉单词中间的空格。result 是新建列表,只有非空且尚未出现的标签才追加。下面是人工推导的逐轮状态:
第1轮:" B " → "B" → "b";追加;["b"] 第2轮:"a" → "a" → "a";追加;["b", "a"] 第3轮:"b" → "b" → "b";已存在;["b", "a"] 第4轮:" " → "" → "";空字符串;["b", "a"] 最终返回:["b", "a"]
顺序保留的是清理后标签的首次出现位置。若 AI 写成 ["a", "b"],请它指出排序发生在哪一行;原函数没有排序。原始列表也仍是 [" B ", "a", "b", " "],没有被替换成小写列表。
还要问清“先清理还是先判重”:本函数先去掉两端空白并转小写,再检查是否已存在。因此原本拼写不同的标签可能合并,不能把结果当成原始标签的逐项副本。

第四步:先写预期,再请 AI 找遗漏
把以下测试放进阅读笔记,不需要执行。每一项检查一种具体行为,空字符串用两个引号表示,避免和没有元素的列表混淆。
T1 [] → []:空列表 T2 ["", " "] → []:去掉空标签 T3 ["Tea", " tea ", "COFFEE"] → ["tea", "coffee"]:清理后去重 T4 ["B", "a", "b"] → ["b", "a"]:保持首次顺序 T5 ["a b", "ab", " A B "] → ["a b", "ab", "a b"]:内部空格保留 T6 [None] → AttributeError:超出输入约定,不能当作空标签跳过
将自己的预期发给 Copilot,要求逐项引用对应语句核对。T6 中 None 没有 strip 方法,函数也未捕获异常;若 AI 自动替它补上异常处理,那是在改变代码,应回到原函数。发现分歧,记录“我的预期、它的说法、代码依据”,不要靠重复提问投票。
交付与隐私:保留原函数、输入约定、六项预期及未解决的问题。只粘贴获准分享的最小代码片段,删除令牌、内部地址和业务数据。本例的纸面分析不等于测试通过;GitHub 也要求人工审查与验证,实际采用前仍须在获准环境运行测试。
资料核查:2026年10月13日。代码与预期为原创教学构造,未调用 Copilot 或执行该函数。