1.编写一个程序,从文件中读取一个单词表,并打印出所有为回文的单词集。例子如下:['deltas','desalt','lasted','salted','slated','staled']['retainers','ternaries']只要单词由同一个字母组成算作回文在单词集合中,根据捕捉关键信息并转化为我掌握的方法原理,我有两个大方向。一种是将每个单词一个一个地读出来,用上面提到的字母词频计数器对单词进行分解。如果将词频计数相同的放入一个集合中;另一个方向是将26个字母排列组合成每个单词,然后去单词表中进行比较。很明显,第二种方法违背了原来的原理,因为这个不在我当前的控制范围内,而且很复杂,需要大量的计算。但是后来我发现有一个更简单的方法,就是利用我掌握的排序功能,对每个单词的字母进行拆分排序,如果结果相同就放在一个集合中。defpaixu_pinjie(word):t=list(word)t.sort()a=''.join(t)returnafin=open('words.txt')d=dict()forlineinfin:word=line.strip()b=paixu_pinjie(word)ifbnotind:d[b]=wordelse:d[b].append(word)returndforkey,valind.items():iflen(val)>1:打印(val)----------------------------------------------------------------------AttributeErrorTraceback(mostrecentcalllast)inasync-def-wrapper()17returnd18--->19forkey,valind.items():20iflen(val)>1:21print(val)AttributeError:'str'对象没有属性'append'这里,问题出在d[b]=word上,word是一个字符串,所以不能用append,如果要给编程的word集添加word,需要把word改成list:defpaixu_pinjie(word):t=list(word)t.sort()a=''.join(t)returnafin=open('words.txt')d=dict()forlineinfin:word=line.strip()b=paixu_pinjie(word)如果b不在d中:d[b]=[word]else:d[b].append(word)returndforkey,valind.items():iflen(val)>1:print(val)这个不会报错,但是发现有一个单词的集合。显然最后一个for循环后面的代码没有生效。发现是for上面的return导致的。据说return只能用在函数中。现在有两种解决方法,一种是把这个return去掉,另一种是把上面写成一个函数defpaixu_pinjie(word):t=list(word)t.sort()a=''.join(t)returnadefall_anagrams(filename):fin=open(filename)d=dict()forlineinfin:word=line.strip().lower()b=paixu_pinjie(word)ifbnotind:d[b]=[word]else:d[b].append(word)返回ddefprint_anagram_set(d):forkey,valind.items():iflen(val)>1:print(val)d=all_anagrams('words.txt')print_anagram_set(d)把上面的代码改成一个函数,另外在word=line.strip()后面加上.lower(),需要把大写字母改成小写字母。决定是否将一段代码写成函数的原则是这段代码是否会被复用,这段代码是否可以分离出来不用。修改上一题中的程序,根据集合中的字数倒序打印。defprint_anagram_sets_in_order(d):t=list()#构建一个空列表来存储key,valind.items():iflen(val)>1:t.append((len(val),val))t.sort(reverse=True)#sort#Printinreverseorderforxint:print(x)print_anagram_sets_in_order(d)因为后面需要复用上面的部分代码,所以需要将其中一部分转换成a功能,否则你必须重新编写它。2.编写一个接受直方图作为参数的choose_from_hist,并从直方图中按频率按比例随机返回一个值。记得有人问过什么是好的python学习资料,我断定好的学习资料之一就是能够通过习题把前后的知识点联系起来。让我们找时间谈谈剩下的。直方图函数已经写好了,剩下的就是根据概率随机取值了。从官方文档中我们可以看到random中有选择满足这个要求。其中,有一个关键的参数weights,可以根据weights后面list中每个数字占总数的概率,在list中选择。在这个例子中,直方图图片会生成一个字典,其中包括没有出现在字母中的单词的频率和对应的字母。我们可以把字典中的键和值分成两个列表。key列表作为随机值列表,value列表赋给weights作为前面取值的概率,下面代码得到defhistogram(s):d=dict()forcins:d[c]=int(d.get(c,'0'))+1#get可以接收一个Key和默认值,如果字典中有这个key,返回对应的值key的,否则返回默认值returnddefchoose_from_hist(s):d=histogram(s)#运行函数a=[在直方图函数result的基础上]b=[]forkey,valind.items():a.append(key)b.append(val)print(a)#key列表print(b)#value列表returnrandom.choices(a,weights=b,k=20)h=histogram('aaaaaabb')choose_from_hist(h)['a','b'][1,1]result返回值列表应该是[6,2]result是[1,1]。检查的原因是直方图函数运行了两次,也就是将直方图函数作为参数传入,运行了一次直方图函数。所以去掉函数中的直方图代码运行defhistogram(s):d=dict()forcins:d[c]=int(d.get(c,'0'))+1returnddefchoose_from_hist(s):a=[]b=[]forkey,valind.items():a.append(key)b.append(val)print(a)print(b)returnrandom.choices(a,weights=b,k=5)#k是一次去k个随机数h=histogram('aaaaaabb')choose_from_hist(h)['a','b'][6,2]Out[85]:['a','a','a','a','b']