- 4.11 练习
4.11 练习
☼ 使用 Python 的帮助功能,找出更多关于序列对象的内容。在解释器中输入
help(str)
,help(list)
和help(tuple)
。这会给你一个每种类型支持的函数的完整列表。一些函数名字有些特殊,两侧有下划线;正如帮助文档显示的那样,每个这样的函数对应于一些较为熟悉的东西。例如x.__getitem__(y)
仅仅是以长篇大论的方式使用x[y]
。☼ 确定三个同时在元组和链表上都可以执行的操作。确定三个不能在元组上执行的列表操作。命名一段使用列表替代元组会产生一个 Python 错误的代码。
☼ 找出如何创建一个由单个项目组成的元组。至少有两种方法可以做到这一点。
☼ 创建一个列表
words = ['is', 'NLP', 'fun', '?']
。使用一系列赋值语句(如words[1] = words[2]
)和临时变量tmp
将这个列表转换为列表['NLP', 'is', 'fun', '!']
。现在,使用元组赋值做相同的转换。☼ 通过输入
help(cmp)
阅读关于内置的比较函数cmp
的内容。它与比较运算符在行为上有何不同?☼ 创建一个 n-grams 的滑动窗口的方法在下面两种极端情况下是否正确:n = 1 和 n =
len(sent)
?☼ 我们指出当空字符串和空链表出现在
if
从句的条件部分时,它们的判断结果是False
。在这种情况下,它们被说成出现在一个布尔上下文中。实验各种不同的布尔上下文中的非布尔表达式,看它们是否被判断为True
或False
。☼ 使用不等号比较字符串,如
'Monty' < 'Python'
。当你做'Z' < 'a'
时会发生什么?尝试具有共同前缀的字符串对,如'Monty' < 'Montague'
。阅读有关“字典排序”的内容以便了解这里发生了什么事。尝试比较结构化对象,如('Monty', 1) < ('Monty', 2)
。这与预期一样吗?☼ 写代码删除字符串开头和结尾处的空白,并规范化词之间的空格为一个单独的空格字符。
- 使用
split()
和join()
做这个任务 - 使用正则表达式替换做这个任务
- 使用
☼ 写一个程序按长度对词排序。定义一个辅助函数
cmp_len
,它在词长上使用cmp
比较函数。◑ 创建一个词列表并将其存储在变量
sent1
。现在赋值sent2 = sent1
。修改sent1
中的一个项目,验证sent2
改变了。- 现在尝试同样的练习,但使用
sent2 = sent1[:]
赋值。再次修改sent1
看看sent2
会发生什么。解释。 - 现在定义
text1
为一个字符串列表的列表(例如表示由多个句子组成的文本)。现在赋值text2 = text1[:]
,分配一个新值给其中一个词,例如text1[1][1] = 'Monty'
。检查这对text2
做了什么。解释。 - 导入 Python 的
deepcopy()
函数(即from copy import deepcopy
),查询其文档,使用它生成任一对象的新副本。
- 现在尝试同样的练习,但使用
◑ 使用列表乘法初始化 n-by-m 的空字符串列表的咧表,例如
word_table = [[''] * n] * m
。当你设置其中一个值时会发生什么事,例如word_table[1][2] = "hello"
?解释为什么会出现这种情况。现在写一个表达式,使用range()
构造一个列表,表明它没有这个问题。◑ 写代码初始化一个称为
word_vowels
的二维数组的集合,处理一个词列表,添加每个词到word_vowels[l][v]
,其中l
是词的长度,v
是它包含的元音的数量。◑ 写一个函数
novel10(text)
输出所有在一个文本最后 10%出现而之前没有遇到过的词。◑ 写一个程序将一个句子表示成一个单独的字符串,分割和计数其中的词。让它输出每一个词和词的频率,每行一个,按字母顺序排列。
◑ 阅读有关 Gematria 的内容,它是一种方法,分配一个数字给词汇,具有相同数字的词之间映射以发现文本隐藏的含义(
http://en.wikipedia.org/wiki/Gematria
,http://essenes.net/gemcal.htm
)。写一个函数
gematria()
,根据letter_vals
中的字母值,累加一个词的字母的数值:>>> letter_vals = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':80, 'g':3, 'h':8,
... 'i':10, 'j':10, 'k':20, 'l':30, 'm':40, 'n':50, 'o':70, 'p':80, 'q':100,
... 'r':200, 's':300, 't':400, 'u':6, 'v':6, 'w':800, 'x':60, 'y':10, 'z':7}
处理一个语料库(
nltk.corpus.state_union
)对每个文档计数它有多少词的字母数值为 666。写一个函数
decode()
来处理文本,随机替换词汇为它们的 Gematria 等值的词,以发现文本的“隐藏的含义”。
◑ 写一个函数
shorten(text, n)
处理文本,省略文本中前 n 个最频繁出现的词。它的可读性会如何?◑ 写代码输出词汇的索引,允许别人根据其含义查找词汇(或它们的发言;词汇条目中包含的任何属性)。
◑ 写一个列表推导排序 WordNet 中与给定同义词集接近的同义词集的列表。例如,给定同义词集
minke_whale.n.01
,orca.n.01
,novel.n.01
和tortoise.n.01
,按照它们与right_whale.n.01
的shortest_path_distance()
对它们进行排序。◑ 写一个函数处理一个词列表(含重复项),返回一个按照频率递减排序的词列表(没有重复项)。例如如果输入列表中包含词
table
的 10 个实例,chair
的 9 个实例,那么在输出列表中table
会出现在chair
前面。◑ 写一个函数以一个文本和一个词汇表作为它的参数,返回在文本中出现但不在词汇表中的一组词。两个参数都可以表示为字符串列表。你能使用
set.difference()
在一行代码中做这些吗?◑ 从 Python 标准库的
operator
模块导入itemgetter()
函数(即from operator import itemgetter
)。创建一个包含几个词的列表words
。现在尝试调用:sorted(words, key=itemgetter(1))
和sorted(words, key=itemgetter(-1))
。解释itemgetter()
正在做什么。◑ 写一个递归函数
lookup(trie, key)
在查找树中查找一个关键字,返回找到的值。扩展这个函数,当一个词由其前缀唯一确定时返回这个词(例如vanguard
是以vang-
开头的唯一的词,所以lookup(trie, 'vang')
应该返回与lookup(trie, 'vanguard')
相同的内容)。◑ 阅读关于“关键字联动”的内容((Scott & Tribble, 2006)的第 5 章)。从 NLTK 的莎士比亚语料库中提取关键字,使用 NetworkX 包,画出关键字联动网络。
◑ 阅读有关字符串编辑距离和 Levenshtein 算法的内容。尝试
nltk.edit_distance()
提供的实现。这用的是动态规划的何种方式?它使用的是自下而上还是自上而下的方法?[另见http://norvig.com/spell-correct.html
]◑ Catalan 数出现在组合数学的许多应用中,包括解析树的计数(6)。该级数可以定义如下:C<sub>0</sub> = 1, and C<sub>n+1</sub> = Σ<sub>0..n</sub> (C<sub>i</sub>C<sub>n-i</sub>)。
- 编写一个递归函数计算第 n 个 Catalan 数 C<sub>n</sub>。
- 现在写另一个函数使用动态规划做这个计算。
- 使用
timeit
模块比较当 n 增加时这些函数的性能。
★ 重现有关著作权鉴定的(Zhao & Zobel, 2007)中的一些结果。
★ 研究性别特异词汇选择,看你是否可以重现一些
http://www.clintoneast.com/articles/words.php
的结果★ 写一个递归函数漂亮的按字母顺序排列输出一个查找树,例如:
chair: 'flesh'
---t: 'cat'
--ic: 'stylish'
---en: 'dog'