列表元素频率统计:字典推导式与for循环赋值字典的结果差异疑问
列表元素频率统计:两段代码结果差异解析
第一段代码(字典推导式)
这段用了Python的字典推导式,语法逻辑是遍历列表生成键值对:
i = ['apple','pear','red','apple','red','red','pear','pear','pear'] d = {x:i.count(x) for x in i} print(d)
运行时会逐个遍历列表i的元素,为每个元素生成x: i.count(x)的键值对。虽然列表里有重复元素,但字典的键具有唯一性,重复的键会覆盖之前的赋值。不过因为i.count(x)统计的是整个列表中x的总出现次数,所以最终每个唯一元素都会留在字典里,得到完整的频率统计结果。
第二段代码(循环逻辑错误)
这段的核心问题是循环内的赋值方式:
i = ['apple','pear','red','apple','red','red','pear', 'pear', 'pear'] d = {} for x in i: d={x:i.count(x)} # 错误根源 print(d)
每次循环时,你不是往已有的字典d中添加键值对,而是直接创建一个仅包含当前元素x的新字典,并将这个新字典覆盖掉原来的d。比如:
- 第一次循环
x='apple',d变成{'apple':2} - 第二次循环
x='pear',d被替换为{'pear':4} - 第三次循环
x='red',d又被替换为{'red':3} - ...直到最后一次循环
x='pear',d最终固定为{'pear':4}
前面的apple和red对应的字典都被后续的新字典覆盖,自然不会出现在最终结果里。
正确的循环实现方式
如果想用循环完成统计,应该直接给字典的键赋值,而非重新创建字典:
i = ['apple','pear','red','apple','red','red','pear', 'pear', 'pear'] d = {} for x in i: d[x] = i.count(x) # 直接更新键x的值,重复键会覆盖但结果正确 print(d)
更高效的写法(避免每次调用count遍历整个列表,时间复杂度从O(n²)优化到O(n)):
i = ['apple','pear','red','apple','red','red','pear', 'pear', 'pear'] d = {} for x in i: d[x] = d.get(x, 0) + 1 # 遇到元素就将对应计数+1 print(d)
内容的提问来源于stack exchange,提问作者Franc42
相关产品推荐
相关产品推荐

