7.12 练习
7-1.字典方法。哪个字典方法可以用来把两个字典合并到一起?
7-2.字典的键。我们知道字典的值可以是任意的Python对象,那字典的键又如何呢?请试着将除数字和字符串以外的其他不同类型的对象作为字典的键,看一看哪些类型可以,哪些不行?对那些不能作字典的键的对象类型,你认为是什么原因呢?
7-3.字典和列表的方法。
(a)创建一个字典,并把这个字典中的键按照字母顺序显示出来。
(b)现在根据已按照字母顺序排序好的键,显示出这个字典中的键和值。
(c)同(b),但这次是根据已按照字母顺序排序好的字典的值,显示出这个字典中的键和值(注意:对字典和哈希表来说,这样做一般没有什么实际意义,因为大多数访问和排序(如果需要)都是基于字典的键,这里只把它作为一个练习)。
7-4.建立字典。给定两个长度相同的列表,比如说,列表[1,2,3,…]和[‘abc’,‘def’,‘ghi’,…],用这两个列表里的所有数据组成一个字典,像这样:{1:‘abc’,2:‘def’,3:‘ghi’,…}
7-5.userpw2.py。下面的问题和例题7.1中管理名字-密码的键值对数据的程序有关。
(a)修改那个脚本,使它能记录用户上次的登录日期和时间(用time模块),并与用户密码一起保存起来。程序的界面有要求用户输入用户名和密码的提示。无论户名是否成功登录,都应有提示,在户名成功登录后,应更新相应用户的上次登录时间戳。如果本次登录与上次登录在时间上相差不超过4个小时,则通知该用户:“You already logged in at:<last_login_timestamp>。”
(b)添加一个“管理”菜单,其中有以下两项:(1)删除一个用户(2)显示系统中所有用户的名字和他们的密码的清单。
(c)口令目前没有加密。请添加一段对口令加密的代码(请参考crypt、rotor,或其他加密模块)。
(d)为程序添加图形界面,例如,用Tkinter写。
(e)要求用户名不区分大小写。
(f)加强对用户名的限制,不允许符号和空白符。
(g)合并“新用户”和“老用户”两个选项。如果一个新用户试图用一个不存在的用户名登录,询问该用户是否是新用户,如果回答是肯定的,就创建该账户。否则,按照老用户的方式登录。
7-6.列表和字典。创建一个简单的股票证券投资数据系统。其中应至少包含4项数据:股市行情显示器符号、所持有的股票、购买价格及当前价位——你可以随意添加其他数据项,比如收益率, 52周最高指数、最低指数,等等。
用户每次输入各列的数据构成一个输出行。每行数据构成一个列表。还有一个总列表,包括了所有行的数据。数据输入完毕后,提示用户选择一列数据项进行排序。把该数据项抽取出来作为字典的键,字典的值就是该键对应行的值的列表。提醒读者:被选择用来排序的数据项必须是非重复的键,否则就会丢失数据,因为字典不允许一个键有多个值。
你还可以选择其他计算输出,比如盈亏比率、目前证券资产价值等。
7-7.颠倒字典中的键和值。用一个字典做输入,输出另一个字典,用前者的键做值,前者的值做键。
7-8.人力资源。创建一个简单的雇员姓名和编号的程序,让用户输入一组雇员姓名和编号。你的程序可以提供按照姓名排序输出的功能,雇员姓名显示在前面,后面是对应的雇员编号。附加题:添加一项功能,按照雇员编号的顺序输出数据。
7-9.翻译。
(a)编写一个字符翻译程序(功能类似于Unix中的tr命令)。我们将这个函数叫做tr(),它有三个字符串做参数:源字符串、目的字符串、基本字符串,语法定义如下:
srcstr的内容是你打算“翻译”的字符集合,dsrstr是翻译后得到的字符集合,而string是你打算进行翻译操作的字符串。举例来说,如果srcstr==‘abc’,dststr==‘mno’,string==‘abcdef,那么tr()的输出将是‘mnodef’。注意这里len(srcstr)==len(dststr)。
在这个练习里,你可以使用内建函数chr()和ord(),但它们并不一定是解决这个问题所必不可少的函数。
(b)在这个函数里增加一个标志参数,来处理不区分大小写的翻译问题。
(c)修改你的程序,使它能够处理删除字符的操作。字符串srcstr中不能够映射到字符串dststr中字符的多余字符都将被过滤掉。换句话说,这些字符没有映射到dststr字符串中的任何字符,因此就从函数返回的字符里被过滤掉了。举例来说:如果srcstr==‘abcdef’, dststr==‘mno’, string==‘abcdefghi’,那么tr()将输出‘mnoghi’。注意这里len(srcstr)>=len(dststr)。
7-10.加密。
(a)用上一个练习的思路编写一个“rot13”翻译器。“rot13”是一个古老而又简单的加密方法,它把字母表中的每个字母用其后的第13个字母来代替。字母表中前半部分字母将被映像到后半部分,而后半部分字母将被映像到前半部分,大小写保持不变。举例来说,‘a’将被替换为‘n’‘X’将被替换为‘K’;数字和符号不进行翻译。
(b)在你的解决方案的基础上加一个应用程序,让它提示用户输入准备加密的字符串(这个算法同时也可以对加密后的字符串进行解密),如下所示:
7-11.定义。什么组成字典中合法的键?举例说明字典中合法的键和非法的键。
7-12.定义。(a)在数学上,什么是集合?
(b)在Python中,关于集合类型的定义是什么?
7-13.随机数。修改练习5-17的代码,使用random模块中的randint()或randrange()方法生成一个随机数集合,从0到9(包括9)中随机选择,生成1~10个随机数。这些数字组成集合A(A可以是可变集合,也可以不是)。同理,按此方法生成集合B。每次新生成集合A和B后,显示结果A|B和A&B。
7-14.用户验证。修改前面的练习,要求用户输入A|B和A&B的结果,并告诉用户他(或她)的答案是否正确,而不是将A|B和A&B的结果直接显示出来。如果用户回答错误,允许他(或她)修改解决方案,然后重新验证用户输入的答案。如果用户三次提交的答案均不正确,程序将显示正确结果。附加题:运用你关于集合的知识,创建某个集合的潜在子集,并询问用户此潜在子集是否真是该集合的子集,要求和主程序一样有显示更正和答案的功能。
7-15.编写计算器。这个练习取材于http://math.hws.edu/在线免费Java教材中的练习12.2。编写一个程序允许用户选择两个集合:A和B,及运算操作符。例如,in、not in、&、|、^、<、<=、 >、>=、==、!=等。(你自己定义集合的输入语法,它们并不一定要像Java示例中那样用方括号括住。)解析输入的字符串,按照用户选择的运算进行操作。你写的程序代码应该比Java该程序的版本更简洁。