
本文详解如何正确使用 `range()` 或更简洁的计数方式,为 json 解析后的字典列表中每个元素动态添加唯一 `id` 键,并避免常见索引覆盖错误。
在处理结构化数据(如从 JSON 文件加载的字典列表)时,常需为每条记录注入唯一标识符(如 id)。一个典型误区是嵌套循环配合 range()——正如问题中所示:外层用 range(1, len(data)+1),内层再遍历 data 并仅对首个元素赋值 d['id'] = i,导致最终所有 id 被反复覆盖为最大值(即 4),且仅首项保留 id 字段。
✅ 正确做法是单层遍历 + 同步计数,无需嵌套。最直观的方式是手动维护计数器:
i = 1
for d in data:
d['id'] = i
i += 1但更 Pythonic、更安全的写法是结合 enumerate() ——它天然提供索引与元素的配对,且默认索引从 0 开始,可通过 start=1 直接生成 1, 2, 3... 序号:
for idx, d in enumerate(data, start=1):
d['id'] = idx完整可运行示例(含文件读写与排序):
立即学习“Python免费学习笔记(深入)”;
import json
# 读取并排序
with open('db.json', 'r') as file:
data = json.load(file)
data.sort(key=lambda x: x['name']) # 按 name 升序排列
# 批量添加 id(推荐方式)
for idx, item in enumerate(data, start=1):
item['id'] = idx
# 验证结果
for item in data:
print(item)
# 输出:
# {'name': 'Joseph', 'id': 1}
# {'name': 'Mary', 'id': 2}
# {'name': 'Peter', 'id': 3}
# {'name': 'Saeed', 'id': 4}⚠️ 注意事项:
- 避免修改原始结构的同时重复遍历:原代码中 for i in range(...): for d in data: 导致每次内层循环都重置 d 引用,break 只中断内层,外层 i 仍递增至 4,最终所有字典被最后一次赋值覆盖。
- enumerate() 比手动计数更健壮,不易出错,且语义清晰。
- 若需生成新列表(不修改原数据),可用列表推导式:[{**d, 'id': idx} for idx, d in enumerate(data, start=1)]。
总结:为字典列表添加自增 ID,核心是“一次遍历、一次赋值”。优先选用 enumerate(data, start=1),简洁、高效、符合 Python 编程习惯。










