《Python核心编程》第6章 序列:字符串、列表和元组 练习

6–1. 字符串.

string 模块中是否有一种字符串方法或者函数可以帮我鉴定一下一个字符串是否是另一个大字符串的一部分?

# coding=utf-8
__author__ = 'Ibuki Suika'

if __name__ == '__main__':
    s1 = raw_input('input a string: ')
    s2 = raw_input('input a substring: ')
    print(s1.find(s2) <> -1)

6–2. 字符串标识符.

修改例6-1 的idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别Python 关键字,对后一个要求,你可以使用keyword 模块(特别是keyword.kelist)来帮你.

import string
import keyword

alphas = string.letters + '_'
nums = string.digits
keywords = keyword.kwlist

print 'Welcome to the Identifier Checker v2.0'
myInput = raw_input('Identifier to test? ')


if myInput[0] not in alphas:
    print 'invalid: first symbol must be alphabetic'
else:
    sets = alphas + nums
    mark = True
    for ch in myInput[1:]:
        if ch not in sets:
            print 'invalid: remaining symbols must be alphanumeric'
            mark = False
            break
    if myInput in keywords:
        print "invalid: can't be keywords"
        mark = False
    if mark:
        print 'okay as an identifier'

6–3. 排序
(a) 输入一串数字,从大到小排列之.
(b) 跟a 一样,不过要用字典序从大到小排列之.

# coding=utf-8
__author__ = 'Ibuki Suika'

if __name__ == '__main__':
    s = raw_input('input some numbers: ').split()
    nums = [int(i) for i in s]

    nums.sort()
    nums.reverse()
    print(nums)

    s.sort()
    s.reverse()
    print(s)

6–4. 算术.

更新上一章里面你的得分测试练习方案,把测试得分放到一个列表中去.你的代码应该可以计算出一个平均分,见练习2-9 和练习5-3.

def level(score):
    if score >= 90:
        return 'A'
    elif score >= 80:
        return 'B'
    elif score >= 70:
        return 'C'
    elif score >= 60:
        return 'D'
    else:
        return 'F'

str = raw_input('your scores: ').split()
average = 0
scores = []
for n in str:
    num = int(n)
    scores.append(level(num))
    average += num

average /= float(len(scores))
print 'average score is %.2f' % average
print scores

6–5. 字符串
(a)更新你在练习2-7 里面的方案,使之可以每次向前向后都显示一个字符串的一个字符.
(b)通过扫描来判断两个字符串是否匹配(不能使用比较操作符或者cmp()内建函数)。附加题:在你的方案里加入大小写区分.
(c)判断一个字符串是否重现(后面跟前面的一致).附加题:在处理除了严格的回文之外,加入对例如控制符号和空格的支持。
(d)接受一个字符,在其后面加一个反向的拷贝,构成一个回文字符串.

s = raw_input('string: ')
for ch in s:
    print ch,
print
for ch in reversed(s):
    print ch,

def issame(str1, str2, sens = False):
    if len(str1) != len(str2):
        return False

    for i, ch in enumerate(str1):
        if not sens:
            if ch.upper() != str2[i].upper():
                break
        else:
            if ch != str2[i]:
                break
    else:
        return True
    return False

str1 = raw_input('str1: ')
str2 = raw_input('str2: ')
print issame(str1, str2)
print issame(str1, str2, True)

def isreverse(s):
    size = len(s)
    for i in range(size // 2):
        if s[i] != s[size - i - 1]:
            return False
    return True

s = raw_input('str: ')
print isreverse(s)
def add_reverse(s):
    return s + s[::-1]

s = raw_input('s: ')
print add_reverse(s)

6–6. 字符串.

创建一个string.strip()的替代函数:接受一个字符串,去掉它前面和后面的空格(如果使用string.*strip()函数那本练习就没有意义了)

def trim(s):
    start = 0
    for i in xrange(len(s)):
        if not s[i].isspace():
            start = i
            break

    end = -1
    for i in xrange(-1, -len(s), -1):
        if not s[i].isspace():
            end = i
            break
    end = None if end == -1 else end + 1
    return s[start:end]

s = trim(raw_input('str: '))
print s
print 'len = %d' % len(s)

6–7. 调试.看一下在例6.5 中给出的代码(buggy.py)
(a)研究这段代码并描述这段代码想做什么.在所有的(#)处都要填写你的注释.
(b)这个程序有一个很大的问题,比如输入6,12,20,30,等它会死掉,实际上它不能处理任何的偶数,找出原因.
(c)修正(b)中提出的问题.
Example 6.4 有bug 的程序(buggy.py)
这是一个用于练习6-7 的程序,判断这个程序是干什么的,在"#"处添加你的注释,找出其中的错
误,并修改之.
1 #!/usr/bin/env python
2
3 #
4 num_str = raw_input('Enter a number: ')
5
6 #
7 num_num = int(num_str)
8
9#
10 fac_list = range(1, num_num+1)
11 print "BEFORE:", 'fac_list'
Edit By Vheavens
Edit By Vheavens
12
13 #
14 i = 0
15
16 #
17 while i < len(fac_list):
18
19 #
20 if num_num % fac_list[i] == 0:
21 del fac_list[i]
22
23 #
24 i = i + 1
25
26 #
27 print "AFTER:", 'fac_list'

#!/usr/bin/env python

#提示输入一个字符串
num_str = raw_input('Enter a number: ')

#把输入的字符串转换为整数
num_num = int(num_str)

#产生1到num_num的数字列表,并输出
fac_list = range(1, num_num+1)
print "BEFORE:", fac_list

#初始化下标为0
i = 0

#遍历列表
while i < len(fac_list):
    #清除num_num的因数
    if num_num % fac_list[i] == 0:
        del fac_list[i]

    #下标加1
    i = i + 1

#输出去除num_num的所有因数后的列表
print "AFTER:", fac_list

#这段程序的问题在于,del一个列表元素后,列表的长度也会发生改变,在删除一个元素的时候,下标也会受到影响,会导致有的元素被遗漏。修改如下:

#!/usr/bin/env python

#提示输入一个字符串
num_str = raw_input('Enter a number: ')

#把输入的字符串转换为整数
num_num = int(num_str)

#产生1到num_num的数字列表,并输出
fac_list = range(1, num_num+1)
print "BEFORE:", fac_list

#初始化下标为0
i = 0

#遍历列表
while i < len(fac_list):
    #清除num_num的因数
    if num_num % fac_list[i] == 0:
        del fac_list[i]
        i = i - 1

    #下标加1
    i = i + 1

#输出去除num_num的所有因数后的列表
print "AFTER:", fac_list

6–8. 列表.

给出一个整数值,返回代表该值的英文,比如输入89 返回"eight-nine"。

附加题:能够返回符合英文语法规则的形式,比如输入“89”返回“eighty-nine”。本练习中的值限定在家0到1,000.

def translate(num):
    assert 0 <= num < 1000, 'out of bound'
    
    num_str1 = ['zero', 'one', 'two', 'three', 'four', 'five', 'six',
               'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve',
               'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen',
                'eighteen', 'nineteen']
    num_str2 = ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy',
                'eighty', 'ninety']
    num_str3 = ' hundred '

    s = '' if num != 0 else num_str1[0] 
    n = num // 100
    if n > 0:
        s = num_str1[n] + num_str3

    n = num % 100
    if 0 < n < 20:
        s = s + num_str1[n]
    elif n >= 20:
        s = s + num_str2[num // 10 % 10 - 2] + ('-' + num_str1[num % 10] if num % 10 != 0 else '')

    return s

print [translate(num) for num in range(1000)]

6–9. 转换.

为练习5-13 写一个姊妹函数, 接受分钟数, 返回小时数和分钟数. 总时间不变,并且要求小时数尽可能大.

def trans_time(mins):
    hours = mins // 60
    minutes = mins % 60
    return (hours, minutes)

mins = input('minutes: ')
print '%d:%d' % trans_time(mins)

6–10.字符串.

写一个函数,返回一个跟输入字符串相似的字符串,要求字符串的大小写反转.比如,输入"Mr.Ed",应该返回"mR.eD"作为输出.

def reverse_case(s):
    result = ''
    for ch in s:
        if ch.islower():
            result += ch.upper()
        elif ch.isupper():
            result += ch.lower()
        else:
            result += ch
    return result

s = raw_input('string: ')
print reverse_case(s)

6–11.转换
(a)创建一个从整数到IP 地址的转换程序,如下格式: WWW.XXX.YYY.ZZZ.
(b)更新你的程序,使之可以逆转换.
def int2ip(num):
    ip = [(num >> i & 0xff) for i in xrange(24, -1, -8)]
    return '%d.%d.%d.%d' % tuple(ip)

def ip2int(ip):
    temp = ip.split('.')
    temp = [int(part) for part in temp]
    temp = [temp[3-i//8] << i for i in xrange(24, -1, -8)]
    return sum(temp)

num = input('number: ')
s = int2ip(num)
print s
print ip2int(s)

6–12.字符串
(a)创建一个名字为findchr()的函数,函数声明如下:

def findchr(string, char)
findchr()要在字符串string 中查找字符char,找到就返回该值的索引,否则返回-1.不能用string.*find()或者string.*index()函数和方法
(b)创建另一个叫rfindchr()的函数,查找字符char 最后一次出现的位置.它跟findchr()工作类似,不过它是从字符串的最后开始向前查找的.
(c)创建第三个函数,名字叫subchr(),声明如下:
def subchr(string, origchar, newchar)
subchr()跟findchr()类似,不同的是,如果找到匹配的字符就用新的字符替换原先字符.返回修改后的字符串.

def findchr(string, char):
    index = -1
    for i, ch in enumerate(string):
        if (ch == char):
            index = i
            break
    return index

def rfindchr(string, char):
    index = -1
    for i, ch in enumerate(string[::-1]):
        if ch == char:
            index = len(string) - i - 1
            break
    return index

def subchr(string, oldchar, newchar):
    s = ''
    for ch in string:
        if ch == oldchar:
            s += newchar
        else:
            s += ch
    return s

6–13.字符串.

string 模块包含三个函数,atoi(),atol(),和atof(),它们分别负责把字符串转换成整数,长整型,和浮点型数字.从Python1.5 起,Python 的内建函数int(),long(),float()也可以做相同的事了,complex()函数可以把字符串转换成复数.(然而1,5 之前,这些转换函数只能工作于数字之上)
string 模块中并没有实现一个atoc()函数,那么你来实现一个,atoc(),接受单个字符串做参数输入,一个表示复数的字符串,例如,'-1.23e+4-5.67j',返回相应的复数对象.你不能用eval()函数,但可以使用complex()函数,而且你只能在如下的限制之下使用complex():complex(real,imag)的real 和imag 都必须是浮点值.

def atoc(string):
    index = max(string.rfind('+'), string.rfind('-'))
    if index > 0:
        if string[index-1] == 'e':
            index = max(string.rfind('+', 0, index-1), string.rfind('-', 0, index-1))
        real = float(string[0:index])
        imag = float(string[index:len(string)-1])
    else:
        if 'j' in string:
            real = 0
            imag = float(string[0:len(string)-1])
        else:
            real = float(string)
            imag = 0
    return complex(real, imag)


6–14.随机数.设计一个"石头,剪子,布"游戏,有时又叫"Rochambeau",你小时候可能玩过,下面是规则.你和你的对手,在同一时间做出特定的手势,必须是下面一种手势:石头,剪子,布.胜利者从下面的规则中产生,这个规则本身是个悖论.
(a) the paper covers the rock,布包石头.
(b)石头砸剪子,
(c)剪子剪破布.

在你的计算机版本中,用户输入她/他的选项,计算机找一个随机选项,然后由你的程序来决定一个胜利者或者平手.注意:最好的算法是尽量少的使用if 语句.

from random import randint

#石头=0,剪子=1,布=2
def rochambeau(human):
    robot = randint(0, 2)
    win = (1, 2, 0)
    return win[human] == robot

6–15.转换
(a)给出两个可识别格式的日期,比如 MM/DD/YY 或者 DD/MM/YY 格式,计算出两个日期间的天数.
(b)给出一个人的生日,计算从此人出生到现在的天数,包括所有的闰月.
(c)还是上面的例子,计算出到此人下次过生日还有多少天.

import time
import datetime

def between(begin, end):
    (year, month, day) = map(int, begin.split('-'))
    d1 = datetime.datetime(year, month, day)
    (year, month, day) = map(int, end.split('-'))
    d2 = datetime.datetime(year, month, day)
    return (d2- d1).days

print between('2011-3-22', '2011-7-26')

6–16.矩阵.

处理矩阵M 和N 的加和乘操作.

from operator import add, mul

def matrix_add(m1, m2):
    m3 = []
    for i, item in enumerate(m1):
        m3 += [map(add, item, m2[i])]
    return m3

def matrix_mul(m1, m2):
    t = [[m2[i][j] for i in xrange(len(m2))] for j in xrange(len(m2[0]))]
    m3 = [[sum(map(mul, item1, item2)) for item2 in t] for item1 in m1]
    return m3

m1 = [[1, 2, 3], [3, 4, 1], [1, 2, 3]]
m2 = [[3, 2, 1], [2, 2, 2], [5, 1, 3]]
print matrix_add(m1, m2)
print matrix_mul(m1, m2)

6–17.方法.

实现一个叫myPop()的函数,功能类似于列表的pop()方法,用一个列表作为输入,移除列表的最新一个元素,并返回它.

def myPop(alist):
    assert isinstance(alist, list)
    alist.pop()
    return alist

6–19.多列输出.

有任意项的序列或者其他容器,把它们等距离分列显示.由调用者提供数据和输出格式.例如,如果你传入100 个项并定义3 列输出,按照需要的模式显示这些数据.这种情况下,应
该是两列显示33 个项,最后一列显示34 个.你可以让用户来选择水平排序或者垂直排序.

#data:数据项,cols:列数,sort=0(不排序)、1(水平排序)、2(垂直排序)
def print_format(data, cols, sort = 0):
    assert cols > 0

    ls = [data[i:i+cols] for i in range(0, len(data), cols)]
    if sort == 1:
        for x in ls:
            x.sort()
    elif sort == 2:
        #补足数据项
        if len(ls[-1]) < cols:
            for i in range(cols-len(ls[-1])):
                ls[-1].append("")

        temp = zip(*ls)
        temp = [sorted(x) for x in temp]
        ls = zip(*temp)

    for x in ls:
        for i in x:
            print i, '\t',
        print


data = [1, 3, 4, 7, 9, 10, 12, 4, 0, 12, 22]
print '多列输出:'
print_format(data, 3)
print '水平排序:'
print_format(data, 3, 1)
print '垂直排序:'
print_format(data, 3, 2) 

你可能感兴趣的:(Python)