think python学习笔记(15)

累加直方图中所有项的值,就是文件中的单词总数

def total_words(hist):
	return sum(hist.values())

不同单词的数量恰好是词典中项的数目

def different_words(hist):
	return len(hist)

最常用单词
使用元组;列表,其中每个元组包含单词和它的频率
具有映射关系的组合常用元组

下面的函数接受一个直方图并且返回一个单词频率的元组列表

def most_common(hist):
	t = []
	for key,value in hist.items():
		t.append((value,key))
	t.sort(reverse=True)
	return t

每一个元组,频率在前,所以这个列表是按照频率排序。下面是输出最常用的十个单词的循环

t = most_common(hist)
for freq,word in t[:10]:
	print(word,freq,sep='\t')

通过关键词sep,让print使用一个制表符(Tab)而不是空格键作为分隔符,所以第二行将对齐

可选形参
程序员也可以自己定义具有可选实参的函数

def print_most_common(hist,num=10):
	t = most_common(hist)
	for freq,word in t[:num]:
		print(word,freq,sep='\t')

第一个形参是必须的,第二个是可选的,num的默认值是10
如果只提供了一个实参

print_most_common(hist)

num将使用默认值,如果提供了两个实参

print_most_common(hist,20)

num获得实参的值,也就是说,可选实参覆盖了默认值

如果一个函数同时拥有必选和可选两类实参,则所有的必选实参必须首先出现,可选实参紧随其后

字典差集
丛书中找到所有没出现在词表words.txt中的单词,可以认为是一个差集问题,也就是,我们应该从一个集合中找到所有没有出现在另一个集合中的单词
substract接受词典d1和d2,并返回一个新的词典,其包括d1中的所有没出现在d2中的键。由于并不关心每个键对应的值,我们将它们都设为None

def substract(d1,d2):
	res = dict()
	for key in d1:
		if key not in d2:
		res[key] = None
	return res

我们可以使用process_file来为words.txt中的单词来构建一个直方图,然后使用substract

words = process_file('words.txt')
diff = substract(hist,words)
for word in diff.keys():
	print(word,end' ')

随机单词
如果想从直方图中随机选择一个单词,最简单的算法是创建一个列表,其中根据其出现的频率,每个单词都有相应个数的拷贝,然后从该列表中选择单词

def random_word(h):
	t = []
	for word,freq in h.items():
		t.extend([word]*q)
	return random.choice(t)

表达式[word]*freq创建一个具有freq和word字符串拷贝的列表,除了它的实参要求是一个序列外,extend方法和append方法很像。

该算法能够满足要求,但是效率不够高,每次选择一个随机单词,都要重建一个很大的列表。一个改进是,创建列表一次,然后进行多次选择,但是列表仍然很大

替代方案:
1.使用keys来获得书中单词的列表
2.创建一个包含单词频率累计和的列表。此列表最后一项是书中单词数目n
3.选择一个从1到n的随机数,使用二分搜索找到该随机数应该被在累计和中插入的索引
4.使用该索引从单词列表中找到相应地单词

马尔科夫分析
一系列随机单词很少有意义,因为相邻的单词之间没有关系。
衡量相邻单词关系的方法之一是马尔科夫分析法,对于一个给定的单词序列,马尔科夫分析法将给出接下里单词的频率。

马尔科夫分析的结果是从每个前缀到所有可能的后缀的映射
给定此映射,能够通过以任意前缀开始并从可能的后缀中随机选择一个的方法,来生成一个随机文本。接下来可以将前缀的结尾和新的后缀组合成下一个前缀,并重复下去。
可以以任意前缀长度进行马尔科夫分析,前缀的长度被称为此分析的阶。

数据结构
选择表达的数据结构:
如何表示前缀
如何表示可能后缀的集合
如果表示从前缀到可能后缀集合的映射

对于前缀,我们需要能够从头部删除单词,并在结尾处加入单词。
可能会想到列表,但是前缀要作为字典的键,所以使用元组
元组可以通过加号运算符形成一个新的元组

def shift(prefix,word):
	return prefix[1:] + (word,)

shift接受一个单词元组prefix和一个字符串word,并形成一个新的元组,它具有orefix中除第一个单词外的全部单词,然后在结尾处增加word
对于后缀,我们需要增加一个新的后缀,并选择一个随机后缀
从列表中选择一个随机元素很容易,在直方图中选择的难度更大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值