Python | 零碎知识(1):字典排序问题
实战:统计Python中的字数
问题
在 Python 中实施函数“count_words()”,该函数将字符串“s”和数字“n”用作输入,并返回“s”中“n”个出现频率最高的单词。返回值应该是一个元组列表-出现频率最高的“n”个单词及其相应的出现次数“[(, ), (, ), …]”,按出现次数的降序排列。
您可以假设所有输入都是小写形式,并且不含标点符号或其他字符(只包含字母和单个分隔空格)。如果出现次数相同,则按字母顺序排列出现次数相同的单词。
例如:
1
2print count_words("betty bought a bit of butter but the butter was bitter",3)
# 输出 = [('butter', 2), ('a', 1), ('betty', 1)]
思路解析及代码
(1)字符切分(split),统计各单词出现的次数(字典get)。(2)使用排序函数(sorted)对字典进行排序,其中定义比较函数compare是关键。代码如下:
功能:统计单词数,先按出现次数(大到小)排序,次数相同时,按单词字母顺序排序1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27def compare(a,b):
if b[1]>a[1]:
return 1
elif b[1]==a[1]:
if a[0]>b[0]:
return 1
else:
return -1
else: return -1
def count_words(s, n):
"""Return the n most frequently occuring words in s."""
##Count the number of occurences of each word in s
d ={}
for word in s.split():
d[word] =d.get(word,0)+1 #D[k] if k in D, else d. d defaults to None
##Sort the occurences in descending order (alphabexcally in case of xes)
#d =sorted(d.iteritems(),key=lambda t:t[1],reverse=True)
#print "按值排序,从大到小 d=", d
vk =sorted(d.items(),cmp=compare)
return vk[:n]
##Return the top n words as a list of tuples (, )
def test_run():
"""Test count_words() with some inputs."""
print count_words("cat bat mat cat bat cat", 3)
print count_words("betty bought a bit of butter but the butter was bitter", 3)
if __name__ == '__main__':
test_run()
##字典排序:sort、reversed、sorted
1、reversed(sequence)
倒序:对一个序列进行倒序排序,注意该函数返回一个倒序迭代器。
1
2print list(reversed(['dream','a','have','I']))
#输出: ['I', 'have', 'a', 'dream']
2、sorted(iterable, cmp=None, key=None, reverse=False)
iterable为可迭代对象, 如果字典键值迭代器;cmp为比较函数;key为排序用的键或键值;reverse指定升降序,True-降序,False-升序(默认)。
1
2
3
4
5
6d = {'bat': 2, 'cat': 3, 'mat': 1} #按键值大到小排序
sorted(d.iteritems(),key=lambda t:t[1],reverse=True)
#输出:[('cat', 3), ('bat', 2), ('mat', 1)]
d = {'bat': 2, 'cat': 3, 'mat': 1} #按键字母顺序排序
sorted(d.iteritems(),key=lambda t:t[0],reverse=False)
#输出:[('bat', 2), ('cat', 3), ('mat', 1)]
cmp ——> cmp(x,y),该函数会在x < y时返回负数,在x > y 时返回正数,如果x = y则返回0(根据你的定义)。如下:
# 内建比较函数cmp的默认方法
cmp(42,32) ---> 1
cmp(99,100) --->-1
cmp(10,10) ---> 0
自定义cmp方法。如下:
1
2
3
4
5
6
7
8# 例1、数字降序排序 | 也可直接用:numbers.sort(reverse=True))
numbers=[5,2,9,7]
numbers.sort(lambda a,b:b-a) #cmp=lambda a,b:b-a
输出 :[9,7,5,2]
# 例2、如果数组成员不是数字,而是其它的类型例如dict,想根据某个属性来排序
persons=[{'name':'zhang3','age':15},{'name':'li4','age':12}]
persons.sort(lambda a,b:a['age']-b['age'])
输出 :[{'age': 12, 'name': 'li4'}, {'age': 15, 'name': 'zhang3'}]
从例子中可知,cmp=lambda a,b:a[‘age’]-b[‘age’], a={‘name’:’zhang3’,’age’:15},b={‘name’:’li4’,’age’:12},a[‘age’]=15-12=b[‘age’]=3>0,返回True。触发reverse=True参数,即从小打大,顺序互换。
注意:在python3.x中取消了cmp参数,也不支持直接往sort()里面传函数了。可以构造排序函数传递给key来实现。