列表元组排序调试:tmp列表测试元素消失与打印时机疑问
元组列表排序异常问题解答
问题描述
尝试对(单词,出现次数)组成的元组列表排序:先按出现次数降序,次数相同时按字母序升序。调试时遇到两个问题:
- 初始添加的测试元素
("abc", 3)消失了; - 当
i=1向tmp添加("is", 3)时未触发print,反而在tmp有两个元素时才打印。
输入文本
hi hi what is your name my name is bond james bond my name is damme van damme claude van damme jean claude van damme
运行代码
text = [] #taking each input line while True: try: text.append(input()) except: break no = [] for i in range(len(text)): no.extend(text[i].split()) co = dict() for word in no: co[word] = co.get(word,0) + 1 #sort by occurence co = sorted(co.items(), key=lambda x:x[1], reverse=True) fin = [] tmp = [("abc", 3)] #a dummy element for testing purpose #sort by alphabetical order if similar occurrence for i in range(1, len(co)): if i == len(co) - 1: if co[i][1] == co[i-1][1]: tmp.append(co[i]) fin.extend(list(sorted(tmp,key= lambda x:x[0]))) break if co[i][1] != co[i-1][1]: fin.append(co[i]) break #compare current value with the previous one and the next one elif co[i][1] == co[i-1][1] and co[i][1] == co[i+1][1]: tmp.append(co[i]) print(i, tmp) #there should be a output line with i = 1 and tmp =[("abc", 3), ("is", 3)] here elif co[i][1] == co[i-1][1] and co[i][1] != co[i+1][1]: tmp.append(co[i]) fin.extend(list(sorted(tmp,key= lambda x:x[0]))) elif co[i][1] != co[i-1][1] and co[i][1] == co[i+1][1]: tmp = [co[i]] elif co[i][1] != co[i-1][1] and co[i][1] != co[i+1][1]: fin.append(co[i]) print(fin)
输出结果
2 [('is', 3), ('name', 3)] 5 [('hi', 2), ('my', 2)] 6 [('hi', 2), ('my', 2), ('bond', 2)] 9 [('what', 1), ('your', 1)] 10 [('what', 1), ('your', 1), ('james', 1)] [('is', 3), ('name', 3), ('van', 3), ('bond', 2), ('claude', 2), ('hi', 2), ('my', 2), ('james', 1), ('jean', 1), ('what', 1), ('your', 1)]
问题原因分析
1. 测试元素("abc", 3)消失的原因
统计后可知,damme的出现次数为4次,是所有单词中最高的,因此排序后的co列表第一个元素为('damme',4)。当循环执行到i=1时,当前元素是('is',3):
- 它的出现次数与前一个元素
('damme',4)不相等,但与后一个元素('name',3)相等,触发了第三个elif分支:
这行代码直接将elif co[i][1] != co[i-1][1] and co[i][1] == co[i+1][1]: tmp = [co[i]]tmp重置为[('is',3)],覆盖了初始的测试元素("abc",3),导致测试元素丢失。
2. i=1时未触发print的原因
print语句仅存在于第一个elif分支中:
elif co[i][1] == co[i-1][1] and co[i][1] == co[i+1][1]: tmp.append(co[i]) print(i, tmp)
i=1时,当前元素('is',3)的次数与前一个元素('damme',4)不相等,不满足该分支的条件,因此不会执行print。直到i=2时,当前元素('name',3)的次数与前后元素的次数都相等,才触发该分支并执行print。
简化修正方案
无需复杂的循环分组,直接在排序时指定复合key即可实现需求:
text = [] while True: try: text.append(input()) except: break no = [] for line in text: no.extend(line.split()) co = dict() for word in no: co[word] = co.get(word, 0) + 1 co["abc"] = 3 # 添加测试元素 # 一次排序完成:先按次数降序,次数相同按字母升序 co_sorted = sorted(co.items(), key=lambda x: (-x[1], x[0])) print(co_sorted)
内容的提问来源于stack exchange,提问作者asdoaihco
相关产品推荐
相关产品推荐

