为何使用.items()遍历defaultdict可解决变量读取类型错误?
为什么遍历defaultdict直接迭代得到的是字符串而非列表?
我来帮你梳理清楚这个问题的根源——其实这是Python字典(包括defaultdict)的默认迭代行为导致的,很多刚接触字典迭代的开发者都会踩这个坑。
问题核心原因
当你直接用for item in your_dict:的方式遍历一个字典时,Python默认迭代的是字典的键(keys),而不是键值对或者对应的值。
回到你的代码:
- 原错误代码里的
for engagement in engagement_by_account:,这里的engagement其实是defaultdict的每个键,也就是字符串类型(比如你的账户ID之类的字符串)。 - 接下来内层循环
for engagement in engagement:就变成了遍历这个字符串的每一个字符,每个字符都是单个字符串,当你尝试执行engagement['total_minutes_visited']时,自然会触发TypeError: string indices must be integers——因为字符串只能用整数下标访问,根本不支持字符串键。
修正代码为什么能正常运行
engagement_by_account.items()方法会返回字典中所有键值对的元组,每个元组的格式是(key, value)。这里的engagement变量就对应了defaultdict中每个键关联的列表(也就是你存储的字典列表),内层循环遍历这个列表里的每个字典,修改total_minutes_visited的类型就完全符合预期了。
举个直观的例子
用一段简单的代码模拟你的场景,就能看清楚差异:
from collections import defaultdict # 模拟你的engagement_by_account结构 engagement_by_account = defaultdict(list) engagement_by_account['user_001'] = [{'total_minutes_visited': '25'}, {'total_minutes_visited': '18'}] engagement_by_account['user_002'] = [{'total_minutes_visited': '30'}] # 直接遍历字典——输出的是键(字符串) print("直接遍历的结果:") for item in engagement_by_account: print(f"类型: {type(item)}, 内容: {item}") # 用items()遍历——输出的是键和对应的值(列表) print("\n用items()遍历的结果:") for key, val in engagement_by_account.items(): print(f"值的类型: {type(val)}, 值的内容: {val}")
运行这段代码后,你会清晰看到两种遍历方式的区别:直接遍历拿到的是字符串类型的键,而items()遍历拿到的才是你需要的列表值。
额外小提示
如果你只需要遍历字典的值,不需要键,也可以用engagement_by_account.values(),这样代码可以写成:
for engagement_list in engagement_by_account.values(): for engagement in engagement_list: engagement['total_minutes_visited'] = float(engagement['total_minutes_visited'])
这样更贴合你只需要处理值的场景,代码可读性也更好。
内容的提问来源于stack exchange,提问作者Alexandre Lutosa
相关产品推荐
相关产品推荐

