内容多参考http://www.cnblogs.com/balian/archive/2012/07/30/2614525.html以及http://hi.baidu.com/deathanybody/item/a81222fe6fd01dc142c36a97
11-1.
参数。比较下面3个函数:
def countToFour1():
for eachNum in range(5):
print eachNum
def countToFour2(n):
for eachNum in range(n, 5):
print eachNum
def countToFour3(n=1):
for eachNum in range(n, 5):
print eachNum
给定如下的输入直到程序输出,你认为会发生什么?向下表11.2填入输出。如果你认为给定的输入会发生错误的话填入“Error”或者如果没有输出的话填入“NONE”。
Input | countToFour1 | countToFour2 | countToFour3 |
2 | ERROR | 2,3,4 | 2,3,4 |
4 | ERROR | 4 | 4 |
5 | ERROR | NONE | NONE |
(nothing) | 0,1,2,3,4 | ERROR | 1,2,3,4 |
11-2.
函数。创建一个函数,返回两个数字的和以及乘积。
【注】根据英文版修改了题目。
def heji(a, b): return a + b, a * b x, y = heji(2, 6) print x print y
注:这个方法就有很多种了,可以自由发挥。
11-3.
函数。在这个练习中,我们将实现max()和min()内建函数。
(a)写分别带两个元素返回一个较大和较小元素,简单的max2()和min2()函数。他们应该可以用任意的Python对象运作。举例来说,max2(4,8)和min2(4,8)会各自每次返回8和4。
(b)创建使用了在a部分中的解来重构max()和min()的新函数my_max()和my_min()。这些函数分别返回非空队列中一个最大和最小值。他们也能带一个参数集合作为输入。用数字和字符串来测试你的解。
(a)
min2 = lambda a, b: a if a < b else b max2 = lambda a, b: a if a > b else b print min2(3,5) print max2(2, 31)
(b)
min2 = lambda a, b: a if a < b else b max2 = lambda a, b: a if a > b else b def my_min(a, b, *num): minNum = min2(a, b) for each in num: minNum = min2(minNum, each) return minNum def my_max(a, b, *num): maxNum = max2(a, b) for each in num: maxNum = max2(maxNum, each) return maxNum print my_min(2, 59, 48, 21, 1) print my_max(45, 1, 4, 98)
11-4.返回值。输入一个以分为单位的总时间,返回一个以小时和分为单位的等价的总时间。
trantime = lambda m: (unicode(m / 60), unicode(m % 60)) print ':'.join(trantime(80))
11-6.
变长参数。写一个称为printf()的函数。有一个值参数,格式字符串。剩下的就是根据格式化字符串的值,要显示在标准输出上的可变参数,格式化字符串中的值允许特别的字符串格式操作指示符,如%d,%f,etc。提示:解是很琐碎的--无需实现字符串操作符功能性,但你需要显示用字符串格式化操作(%)。
注:这个题没明白,balian上有英文原题。
11-7.
用map()进行函数式编程。给定一对同一大小的列表,如[1, 2, 3, ...]和['abc', 'def', 'ghi', ...],将两个列表归并为一个由每个列表元素组成的元组的单一列表,以使我们的结果看起来像这样:{[(1, 'abc'), (2, 'def'), (3, 'ghi'), ...}。(虽然这问题在本质上和第6章的一个问题类似,那时两个解没有直接的联系)然后创建用zip内建函数创建另一个解。
a = ['jia', 'wo', 'ma'] b = ['gei', 'hao', '?'] print map(None, a, b) print zip(a, b)
11-8.
用filter()进行函数式编程,使用练习5-4你给出的代码来决定闰年。更新你的代码以便使它成为一个函数,如果你还没有那么做的话。然后写一段代码来给出一个年份的列表并返回一个只有闰年的列表。然后将它转化为用列表解析。
def oddyear(n): if (n % 4 == 0 and n % 100 != 0) or n % 400 ==0: return n print filter(oddyear, range(1999, 2030))
转化为列表解析:
print [n for n in range(1999, 2030) if n % 4 == 0 and n % 100 != 0 or n % 400 == 0]
注:这个真的很爽。
11-9.
用reduce()进行函数式编程。复习11.7.2部分,阐述如何用reduce()计算数字集合的总和。修改它并创建一个叫average()的函数来计算每个数字集合的简单的平均值。
print reduce((lambda a, b: a + b), range(6)) / float(6)
11-10.
用filter()进行函数式编程。在unix文件系统中,在每个文件夹或者目录中都有两个特别的文件:"."表示现在的目录,".."表示父目录。给出上面的知识,看一下os.listdir()函数的文档并描述这段代码做了什么:
files = filter(lambda x: x and x[0] != '.', os.listdir(folder))
没有unix系统,从代码上看是对folder下的文件过滤,只要文件夹不以.开头都可以通过。
11-11.
用map()进行函数式编程。写一个使用文件名以及通过除去每行中所有排头和最尾的空白来“清洁”文件。在原始文件中读取然后写入一个新的文件,创建一个新的或者覆盖掉已存在的。给你的用户一个选择来决定执行哪一个。将你的解转换成使用列表解析。
#codint=utf-8 f = open('test1.txt') qc = lambda x: x.strip() res = map(qc, f) f.close() print res
注:不知道咋回事,写入文件的时候老是提示expected character buffer object错误,暂时就写到打印出来。
11-12.
传递函数。给在这章中描述的testit()函数写一个姊妹函数。timeit()会带一个函数对象(和参数一起)并计算出用了多少时间来执行这个函数,而不是测试执行时的错误。返回下面的状态:函数返回值、消耗的时间。你可以用time.clock()或者time.time(),无论哪一个给你提了较高的精度(一般的共识是在POSIX上用time.time(),在win32系统上用time.clock())。注意:timeit()函数与模块timeit不相关(在python2.3中引入)。
import time def timeit(func): start_time = time.clock() result = func end_time = time.clock() return (result, end_time - start_time) def func(a, b): return a * b print timeit(func(23, 12))
11-13.
使用reduce()进行函数式编程以及递归。在第8章中,我们看到N的阶乘或者N作为从1到N所有数字的乘积。
(a)用一分钟写一个带x,y并返回他们乘积的名为mult(x,y)的简单小巧的函数。
(b)用你在(a)中创建的mult()函数以及reduce来计算阶乘。
(c)彻底抛弃掉mult()的使用,用lamda表达式替代。
(d)在这章中,我们描绘了一个递归解决方案来找到N!用你在上面问题中完成的timeit()函数,并给三个版本阶乘函数计时(迭代的,reduce()和递归)。
import time def timeit(func): start_time = time.clock() result = func end_time = time.clock() return(result, end_time - start_time) def mult(a, b): return a * b print timeit(reduce(mult, range(9)[1:])) print timeit(reduce((lambda a, b: a * b), range(9)[1:])) def nmult(a): if a == 1: return 1 else: return a * nmult(a - 1) print timeit(nmult(8))
运算结果是:
(40320, 2.2349209187201168e-06) (40320, 2.5142860335601288e-06) (40320, 2.2349209187200723e-06)
递归竟然是最快的,我还第一次知道。
11-14.
递归。我们也来看下在第8章中的斐波纳契数列。重写你先前计算斐波纳契数列的解(练习8-9)以便你可以使用递归。
def fibo(n): if n == 1: return 1 elif n == 2: return 1 else: return fibo(n - 1) + fibo(n - 2) print fibo(6)
11-15.
递归。重写练习6-5的解,用递归向后打印一个字符串。用递归向前以及向后打印一个字符串。
暂时不会。