第六章
第六章讲述的是Python里重要的数据类型:字符串、列表、和元组。他们都有自己的操作方法、内建函数,灵活的运用这些数据类型可以更加强大的发挥出Python的能力。这次解析中有较多的代码,这些代码只经过了简单的测试,所有仅供参考啦。如有错情还请包涵指正!
第一题:
字符串。string模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分?
答:有。string模块中find内建函数,string.find(str,beg=0,end=len(str)),在beg和end之间查找str字符串。
string模块中rfind内建函数,string.rfind(str,beg=0,end=len(str)),类似于find()函数,不过是从右边开始查找。
string模块中index内建函数,string.index(str,beg=0,end=len(str)),类似于find()函数,不过查找不存在会返回一个异常。
string模块中rindex内建函数,string.rindex(str,beg=0,end=len(str)),类似于index()函数,不过是从右边开始查找。
成员操作符 in 和 not in
第二题:
字符串标识符。修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来帮你。
答:
#-*- coding:utf-8 -*-
#2015-03-12
import string
import keyword
alphas = string.letters + '_' #定义字符串敞亮,letters包含全部大小写字母
nums = string.digits #字符串常量,包含数字0~9
print 'Welcome to the Identifier Checker v2.0'
while True:
try:
myInput = raw_input('Identifier to test\n')
if myInput[0] not in alphas:
print 'invalid:first symbol must be alphabetic' #检测第一个字符
else:
for otherchar in myInput[1:]: #检测中间字符
if otherchar not in alphas+nums:
print 'invalid:remaining sysbols must be alpanumeric'
break
else:
if myInput not in keyword.kwlist: #检测是否属于关键字
print 'okay as an identifier'
else:
print 'connot be keyword'
except EOFError:
break
第三题:
排序
(a) 输入一串数字,从大到小排列之。
(b) 跟 a 一样,不过要用字典序从大到小排列之.。
答:
#-*- coding:utf-8 -*-
#2015-03-12
num = raw_input()
alist = []
blist = []
for i in num:
alist.append(int(i))
blist.append(int(i))
blist.sort()
alist = sorted(alist)
print alist
print blist
第四题:
算术。 更新上一章里面你的得分测试练习方案,把测试得分放到一个列表中去。你的代码应该可以计算出一个平均分,见练习 2-9 和练习 5-3。
答:
#-*- coding:utf-8 -*-
#2015-03-12
def test(a):
if a < 0 or a > 100:
print 'Please input a corrent number!'
elif a >= 90:
print 'A'
elif a >= 80:
print 'B'
elif a >= 70:
print 'C'
elif a >= 60:
print 'D'
else:
print 'F'
if __name__=='__main__':
count = []
while True:
try:
n = input()
count.append(n)
test(n)
except EOFError:
break
print 'The average is : %f' % (sum(count)/len(count))
第五题:
字符串
(a)更新你在练习 2-7 里面的方案,使之可以每次向前向后都显示一个字符串的一个字符。
(b)通过扫描来判断两个字符串是否匹配(不能使用比较操作符或者 cmp()内建函数)。附加题: 在你的方案里加入大小写区分。
(c)判断一个字符串是否重现(后面跟前面的一致)。附加题:在处理除了严格的回文之外,加入对例如控制符号和空格的支持。
(d)接受一个字符,在其后面加一个反向的拷贝,构成一个回文字符串。
(a)
#-*- coding:utf-8 -*-
#2015-03-12
astring = raw_input()
for i in astring: #从前向后遍历
print i,
for i in astring[::-1]: #从后向前遍历
print i,
(b)
#-*- coding:utf-8 -*-
#2015-03-12
astring = raw_input()
bstring = raw_input()
alist = list(astring)
blist = list(bstring)
for i,j in zip(alist,blist):
if i is not j :
print 'Two string is different'
break
else:
print 'Two string is same'
(c)
#-*- coding:utf-8 -*-
#2015-03-12
def huiwen(astring):
if len(astring)%2!=0:
print 'It is not a palindorom.'
else:
bstring = astring[len(astring)::-1]
if cmp(astring[:len(astring)], bstring)==0:
print 'It is a palindorom.'
else:
print 'It is not a palindorom.'
if __name__=='__main__':
astring = raw_input()
huiwen(astring)
(d)
#-*- coding:utf-8 -*-
#2015-03-12
def huiwen(astring):
return astring+astring[::-1]
if __name__=='__main__':
astring = raw_input()
print huiwen(astring)
第六题:
字符串.创建一个 string.strip()的替代函数:接受一个字符串,去掉它前面和后面的空格(如果使用 string.*strip()函数那本练习就没有意义了)
答:
#-*- coding:utf-8 -*-
#2015-03-12
def mystrip(astr,c=' '):
alist = []
temp = 0
for i,j in enumerate(astr):
if j==c:
alist.append(astr[temp:i])
temp = i+1
alist.append(astr[temp:])
return alist
if __name__=='__main__':
astring = raw_input()
blist = mystrip(astring) #可以传入第二个参数,若没有则默认为空格
print blist
第七题:
调试。看一下在例 6.5 中给出的代码(buggy.py)
(a)研究这段代码并描述这段代码想做什么,在所有的(#)处都要填写你的注释。
(b)这个程序有一个很大的问题,比如输入 6,12,20,30,等它会死掉,实际上它不能处理任何的偶数,找出原因。
(c)修正(b)中提出的问题.。
答:
#-*- coding:utf-8 -*-
#输入一个字符串
num_str = raw_input()
#转换为int类型
num_num = int(num_str)
#创建一个长度为num_num的列表
fac_list = range(1,num_num+1)
print "BEFORE:",'fac_list'
#声明变量i
i = 0
#
while i <len(fac_list):
#
if num_num % fac_list[i] == 0:
del fac_list[i]
#计数器增加
i = i+1
#最后输出
print "AFTER:",'fac_list'
并没有发现题目所说的不能处理偶数的问题,程序正常输出!
第八题:
列表。给出一个整形值,返回代表该值的英文,比如输入89返回“eight-nine”。附加题:能够返回符合英文语法规则形式,比如输入“89”返回“eighty-nine”。本练习中的值限定在0~1000。
答:
#-*- coding:utf-8 -*-
#2015-03-13
def Test(num):
#定义列表
onenum = ['zero','one','two','three','four','five','six','seven','eight','nine']
tennum = ['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
twonum = ['','','twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety']
if num < 10:
return onenum[num]
elif num>=10 and num <20:
if num == 10:
return 'ten'
temp = num%10
return tennum[temp]
elif num>=20 and num <100:
temp = num%10
out = twonum[num/10]
if temp!=0:
out = out + '-' + onenum[temp]
return out
elif num==1000:
return 'one thousand'
else:
temp = num/100
num = num - temp*100
out = onenum[temp] + '-hundred'
temp = num/10
if num!=0:
out = out + ' and '
if num<10:
out = out + onenum[num]
elif num >=10 and num <20:
out = out + tennum[num%10]
elif num >=20 and num <100:
out = out + twonum[num/10]
if num%10!=0:
out = out + '-' + onenum[num%10]
return out
if __name__ == '__main__':
num = input('Please input a number(0~1000):')
print Test(num)
第九题:
转换。为练习5-13写一个姊妹函数,接受分钟数,返回小时数和分钟数。总时间不变,并且要求小时数尽可能大。
答:
#-*- coding:utf-8 -*-
#2015-03-13
def Test(num):
timelist = []
timelist.append(num/60)
timelist.append(num%60)
return timelist
if __name__ == '__main__':
num = input('Please input minutes:')
out = Test(num)
print 'The time is %d hours %d minutes' % (out[0],out[1])
第十题:
字符串。写一个函数,返回一个跟输入字符串相似的字符串,要求字符串的大小写翻转。比如,输入“Mr.Ed”,应该返回“mR.eD”作为输出。
答:
#-*- coding:utf-8 -*-
#2015-03-13
firststring = raw_input()
#直接用一个swapcase()函数即可
secondstring = firststring.swapcase()
print secondstring
第十一题:
转换。
(a)创建一个从整形到IP地址的转换程序,如下格式:WWW.XXX.YYY.ZZZ
(b)更新你的程序,使之可以逆转换。
答:
#-*- coding:utf-8 -*-
#2015-03-13
#十进制转换为二进制
def convert1(myip):
myip = myip.split('.')
for i in range(len(myip)):
myip[i] = bin(int(myip[i]))
return myip
#二进制转换为十进制
def convert2(myip):
myip = myip.split('.')
for i in range(len(myip)):
myip[i] = int(myip[i],2)
return myip
if __name__ == '__main__':
ip10 = raw_input('Please input decimal IP:')
out = convert1(ip10)
print 'The first convert %s.%s.%s.%s' % (out[0],out[1],out[2],out[3]) #每个输出开头会有0b,Python表示这是一个二进制数
ip2 = raw_input('Please input binary IP:')
out = convert2(ip2)
print 'The second convert %s.%s.%s.%s' % (out[0],out[1],out[2],out[3])
第十二题:
(a)创建一个名为findchr()的函数,函数声明如下:
def findchr(string,char)
findchar要在字符串string中查找字符char,找到就返回该值的索引,否则返回-1。不能用string.find()或者string.index()函数和方法。(b)创建另一个叫rfindchar()的函数,查找字符char最后一次出现的位置。它跟findchar()工作类似,不过他是从字符串最后向前查找的。
(c)创建第三个函数,名字叫subchar(),声明如下:
def subchar(string,origchar,newchar)
subchar()跟findchar()类似,不同的是,如果能找到匹配的字符,就用新的字符替换原先的字符。返回修改后的字符串。答:
#-*- coding:utf-8 -*-
#2015-03-14
def findchar(mystring,char):
for i,j in enumerate(mystring):
if j==char:
return i
else:
return -1
def rfindchar(mystring,char):
mystring = mystring[::-1]
for i,j in enumerate(mystring):
if j==char:
return len(mystring)-i-1
else:
return -1
def subchar(mystring,origchar,newchar):
newstring=''
for i in mystring:
if i!=origchar:
newstring += i
else:
newstring += newchar
return newstring
if __name__ == '__main__':
mystring = raw_input('Input you string:')
print 'What do you want?'
print "Find a char from bengin: 'a'"
print "Find a char from end: 'b'"
print "Find a char and change it: 'c'"
order = raw_input()
if order=='a':
char = raw_input('Input a char you want to find:')
out = findchar(mystring, char)
if out!=-1:
print 'The position of the char from the begin is:%d' % out
else:
print 'No char in string'
elif order=='b':
char = raw_input('Input a char you want to find:')
out = rfindchar(mystring, char)
if out!=-1:
print 'The position of the char from the end is:%d' % out
else:
print 'No char in string'
else:
char = raw_input('Input a char you want to change:')
newchar = raw_input('Input a newchar:')
if findchar(mystring,char)==-1:
print 'No char in string'
else:
out = subchar(mystring, char,newchar)
print 'The new string is:%s' % out
第十三题:
字符串string模块包含三个函数,atoi()、atol()、和atof(),他们分别负责把字符串转换成整形、长整形和浮点型数字。从Python1.5起,Python的内建函数int()、long()、float()也可以做同样的事情了,complex()函数可以把字符串转换成复数(然而1.5之前这些函数只能工作于数字之上)。string模块并没有实现一个atoc()函数,那么你来实现一个atoc(),接受单个字符串做参数输入,一个表示复数的字符串,例如‘-1.23+4-5.6j’,返回相应的复数对象。你不能用eval()函数,但可以用cmplex()函数,而且你只能在如下的限制下使用:complex():complex(real,imag)的real和imag都必须是浮点值。
答:
#-*- coding:utf-8 -*-
#2015-03-14
def atoc(mystring):
a = mystring.rfind('+')
b = mystring.rfind('-')
c = max(a,b)
real = float(mystring[:c])
imag = float(mystring[c+1:len(mystring)-1])
return complex(real,imag)
if __name__ == '__main__':
mystring = raw_input()
print atoc(mystring)
第十四题:
随机数。设计一个“石头、剪刀、布”游戏,有时又叫“Rochambeau”,你小时候可能玩过,下面是规则。你和你的对手,在同一时间作出手势,必须是下面的一种:石头、剪刀、布。胜利者从下面的规则产生,这个规则本身是个悖论。
(a)布包石头
(b)石头砸剪子
(c)剪子剪破布
你的计算机版本中,用户输入他/她的选项,计算机找一个随机选项,然后有你的程序来决定一个胜利者或者平手。注意:最好的算法是尽量少使用if语句。
答:
#-*- coding:utf-8 -*-
#2015-03-14
import random
# 石头、剪刀、布
#输入 1 2 3
#电脑 3 1 2
def Rochambeau(pnum,cnum):
if pnum-cnum==0:
return 1
elif pnum==1:
if pnum-cnum==-2:
return 0
else:
return -1
elif pnum==2:
if pnum-cnum==1:
return 0
else:
return -1
else:
if pnum-cnum==2:
return 0
else:
return -1
if __name__ == '__main__':
pnum = random.choice([1,2,3])
print "Input you choice:"
print "'1':石头 '2':剪刀 '3': 布"
cnum = input()
out = Rochambeau(pnum, cnum)
if out==1:
print 'You are victory!'
elif out==0:
print 'Dogfall!'
else:
print 'You are lost!'
第十五题:
转换。
(a)给出两个可以识别的日期,比如MM/DD/YY或者DD/MM/YY格式,计算出这两个日期间的天数。
(b)给出一个人的生日,计算出此人出生到现在的天数,包括所有的闰月。
(c)还是上面的例子,计算出此人下次生日还有多少天。
答:(这个程序写的比较累赘)
#-*- coding:utf-8 -*-
#2015-03-14
from datetime import *
#计算日期间隔
def interval():
print 'What input Presentation od you like?'
key = input("'1':MM/DD/YY '2':DD/MM/YY ")
date1 = raw_input('Please input the first time:')
date2 = raw_input('Please input the first time:')
date1 = date1.split('/')
date2 = date2.split('/')
if key==1:
day1 = int(date1[1])
mouth1 = int(date1[0])
year1 = int(date1[2])
day2 = int(date2[1])
mouth2 = int(date2[2])
year2 = int(date2[2])
else:
day1 = int(date1[0])
mouth1 = int(date1[1])
year1 = int(date1[2])
day2 = int(date2[0])
mouth2 = int(date2[1])
year2 = int(date2[2])
firstdate = date(year1,mouth1,day1)
seconddate = date(year2,mouth2,day2)
print 'The interval is',seconddate - firstdate
#计算活了多少天
def life():
print 'What input Presentation od you like?'
key = input("'1':MM/DD/YY '2':DD/MM/YY ")
birth = raw_input('Please input your birthday:')
birth = birth.split('/')
d = date.today()
if key==1:
day = int(birth[1])
mouth = int(birth[0])
year = int(birth[2])
else:
day = int(birth[0])
mouth = int(birth[1])
year = int(birth[2])
firstdate = date(year,mouth,day)
seconddate = date(d.year,d.month,d.day)
print 'Your life is',seconddate - firstdate
#计算下次生日多少天
def birthday():
print 'What input Presentation od you like?'
key = input("'1':MM/DD/YY '2':DD/MM/YY ")
birth = raw_input('Please input your birthday:')
birth = birth.split('/')
d = date.today()
if key==1:
firstdate = date(d.year,int(birth[0]),int(birth[1]))
else:
firstdate = date(d.year,int(birth[1]),int(birth[0]))
seconddate = date(d.year,d.month,d.day)
if (d.month>firstdate.month) or (d.month==firstdate.month and d.day>firstdate.day):
print 'Next birthday has',date(d.year+1,int(birth[0]),int(birth[1]))-seconddate,'days'
else:
print 'Next birthday has',firstdate - seconddate,'days'
if __name__ == '__main__':
print 'What do you want? Please choose!'
print "'a':计算时间间隔"
print "'b':计算生命日期"
print "'c':计算下次生日"
choose = raw_input()
if choose=='a':
interval()
elif choose=='b':
life()
else:
birthday()
第十六题:
矩阵。处理矩阵M和N的加和乘的操作。
答:(这个也是比较累赘)
#-*- coding:utf-8 -*-
#2015-03-15
import sys
#矩阵的和
def mat_sum(amatrix,bmatrix,m,n):
cmatrix = []
if len(amatrix)!=len(bmatrix) or len(amatrix[0])!=len(bmatrix[0]):
print '两个矩阵行和列不一致,无法求和'
return 0
else:
for i in range(m):
temp = []
for j in range(n):
temp.append(int(amatrix[i][j])+int(bmatrix[i][j]))
cmatrix.append(temp)
return cmatrix
矩阵的积
def mat_multiplication(amatrix,bmatrix):
cmatrix = []
if len(amatrix[0])!=len(bmatrix):
print '第一个矩阵的列不等于第二个矩阵的行,无法求积'
return 0
else:
for i in range(len(amatrix)):
temp = []
for j in range(len(bmatrix[0])):
g = 0
for k in range(len(amatrix[0])):
g += int(amatrix[i][k])*int(bmatrix[k][j])
temp.append(g)
cmatrix.append(temp)
return cmatrix
if __name__ == '__main__':
amatrix = []
bmatrix = []
print '请输入第一个矩阵的行和列'
m = input()
n = input()
print '请输入矩阵的元素'
for i in range(m):
data = raw_input()
data = data.split()
amatrix.append(data)
print '请输入第二个矩阵的行和列'
m = input()
n = input()
print '请输入矩阵的元素'
for i in range(m):
data = raw_input()
data = data.split()
bmatrix.append(data)
cmatrix = mat_sum(amatrix, bmatrix, m, n)
if cmatrix==0:
sys.exit(0)
print '两个矩阵的和为:'
for i in range(m):
for j in range(n):
print cmatrix[i][j],
print '\n',
cmatrix = mat_multiplication(amatrix, bmatrix)
if cmatrix==0:
sys.exit(0)
print '两个矩阵的积为:'
for i in range(len(cmatrix)):
for j in range(len(cmatrix[0])):
print cmatrix[i][j],
print '\n',
第十七题:
方法。实现一个叫myPop()的函数,功能类似于列表的pop()方法,用一个列表作为输入,移除列表的最新一个元素,并返回它。
答:
def myPop(alist):
temp = alist[len(alist)-1]
del alist[len(alist)-1]
return temp
第十八题:
zip()内建函。在6.13.2节里面关于zip()函数的例子里面,zip(fn,ln)返回的是什么?
答:
返回一个列表,例如:
>>> fn = [1,2]
>>> ln = [3,4]
>>> zip(fn,ln)
[(1, 3), (2, 4)]
>>>
第十九题:
多列输出。有任意项的序列或是其他容器,把他们等距离分列显示。由调用者提供数据和输出格式。例如,如果你传入100个项并定义3列输出,按照需要的模式显示这些数据。这种情况下,应该是有两列显示33个项,最后一列显示34个。你可以让用户来选择水平排序或垂直排序。答:(这题主要考察的是输出,我就直接定义了一个列表,这里用到了很多循环,其中有些循环其实写的很不好,后续我会写一篇文章讲提升Python效率的,到时候会给出解释。)
#-*- coding:utf-8 -*-
#2015-03-15
def myOutput(alist,key):
if key==1:
L = input('输出几行:')
temp = len(alist)/L
for i in range(temp*(L-1)):
if i%temp==0 and i!=0:
print '\n',alist[i],
else:
print '%0d' % alist[i],
print '\n',
for i in range(temp*(L-1),len(alist)):
print '%0d' % alist[i],
else:
L = input('输出几列:')
blist = []
for i in range(len(alist)/L):
temp = []
for j in range(L):
temp.append(i+j*(len(alist)//L))
blist.append(temp)
for i in range(len(alist)-L*(len(alist)//L)):
temp = []
for j in range(L-1):
temp.append(' ')
temp.append(alist[L*(len(alist)//L)+i])
blist.append(temp)
for i in range(len(blist)):
for j in range(len(blist[0])):
print blist[i][j],
print '\n',
if __name__ == '__main__':
alist = []
for i in range(100):
alist.append(i)
print '你想按什么方式输出?'
print "'1':行 '2':列"
key = input()
myOutput(alist,key)