11-3 函数。
在这个练习中,我们将实现max()和min()内建函数。
(a) 写分别带两个元素返回一个较大和较小元素,简单的max2()核min2()函数。他们应该可以用任意的python 对象运作。举例来说,max2(4,8)和min2(4,8)会各自每次返回8 和4。(b) 创建使用了在a 部分中的解来重构max()和min()的新函数my_max()和my_min().这些函数分别返回非空队列中一个最大和最小值。它们也能带一个参数集合作为输入。用数字和字符串来测试你的解。
max2 = lambda x, y: x if cmp(x, y) > 0 else y
min2 = lambda x, y: y if cmp(x, y) > 0 else x
def my_max(*data):
ret = data[0]
for i in data:
ret = max2(ret, i)
return ret
def my_min(*data):
ret = data[0]
for i in data:
ret = min(ret, i)
return ret
if __name__ == '__main__':
print max2('82', '1233')
print min2('82', '1233')
print max2(82, 1233)
print min2(82, 1233)
print my_max('12', '0123', '90')
print my_min('12', '0123', '90')
print my_max(1, 9, 4)
print my_min(1, 9, 4)
11–4. 返回值。
给你在5-13 的解创建一个补充函数。创建一个带以分为单位的总时间以及返回一个以小时和分为单位的等价的总时间。
transtime = lambda m: (m / 60, m % 60)
if __name__ == '__main__':
print transtime(70)
11–6. 变长参数。
下一个称为printf()的函数。有一个值参数,格式字符串。剩下的就是根据格式化字符串上的值,要显示在标准输出上的可变参数,格式化字符串中的值允许特别的字符串
格式操作指示符,如%d, %f, etc。提示:解是很琐碎的----无需实现字符串操作符功能性,但你需要显示用字符串格式化操作(%)
def printf(fmt, *varlist):
print fmt % varlist
if __name__ == '__main__':
printf('%d-%d-%s', 2011, 3, '18')
11–7. 用map() 进行函数式编程。
给定一对同一大小的列表, 如[1 , 2 , 3] 和['abc','def','ghi',....],将两个标归并为一个由每个列表元素组成的元组的单一的表,以使我们的结果看起来像这样:{[(1, 'abc'), (2, 'def'), (3, 'ghi'), ...}.(虽然这问题在本质上和第六章的一个问题相似,那时两个解没有直接的联系)然后创建用zip 内建函数创建另一个解。
def my_zip(ls1, ls2):
assert len(ls1) == len(ls2)
ls = map(None, ls1, ls2)
return ls
if __name__ == '__main__':
print my_zip([1, 2, 3], [4, 5, 6])
11–8. 用filer()进行函数式编程.
使用练习5-4 你给出的代码来决定闰年。更新你的代码一边他成为一个函数如果你还没有那么做的话。然后写一段代码来给出一个年份的列表并返回一个只有闰年的列表。然后将它转化为用列表解析。
is_leap = lambda year: (year % 400 == 0) or (year % 100 != 0) and (year % 4 ==0)
if __name__ == '__main__':
print filter(is_leap, [2000, 1984, 1986, 1996, 1991])
11–9. 用reduce()进行函数式编程。
复习11.7.2 部分,阐述如何用reduce()数字集合的累加的代码。修改它,创建一个叫average()的函数来计算每个数字集合的简单的平均值。
import operator
def average(numlist):
total = reduce(operator.add, numlist)
return float(total) / len(numlist)
if __name__ == '__main__':
print average([i for i in range(1, 11)])
11–11.用map()进行函数式编程。
写一个使用文件名以及通过除去每行中所有排头和最尾的空白来“清洁“文件。在原始文件中读取然后写入一个新的文件,创建一个新的或者覆盖掉已存在的。给你的用户一个选择来决定执行哪一个。将你的解转换成使用列表解析。
def delspace(filename):
func = lambda text: text.strip()
with open(filename, 'r+') as f:
ls = map(func, f)
f.seek(0)
f.write(''.join(ls))
if __name__ == '__main__':
delspace('wx.txt')
11–12. 传递函数。
给在这章中描述的testit()函数写一个姊妹函数。timeit()会带一个函数对象(和参数一起)以及计算出用了多少时间来执行这个函数,而不是测试执行时的错误。返回下面的状态:函数返回值,消耗的时间。你可以用time.clock()或者time.time(),无论哪一个给你提供了较高的精度。(一般的共识是在POSIX 上用time.time(),在win32 系统上用time.clock())
注意:timeit()函数与timeit 模块不相关(在python2.3 中引入)
import time
def timeit(f):
def counter(*args, **kargs):
start = time.clock()
ret = f(*args, **kargs)
end = time.clock()
print 'function:', f.__name__
print 'spend time:', end - start
print 'return value:', ret
print
return ret
return counter
@timeit
def test():
num = 0
for i in xrange(100000):
num += i
return num
if __name__ == '__main__':
test()
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(f):
def counter(*args, **kargs):
start = time.clock()
ret = f(*args, **kargs)
end = time.clock()
print 'function:', f.__name__
print 'spend time:', end - start
print 'return value:', ret
print
return ret
return counter
@timeit
def fac1(n):
total = 1
for i in xrange(1, n+1):
total *= i
return total
@timeit
def fac2(n):
return reduce(lambda x, y: x * y, xrange(1, n+1))
def fac3(n):
if n == 1:
return 1
else:
total = fac3(n-1) * n
return total
if __name__ == '__main__':
fac1(100)
fac2(100)
fac3(100)
11–14. 递归。
我们也来看下在第八章中的Fibonacci 数字。重写你先前计算Fibonacci 数字的解(练习8-9)以便你可以使用递归。
def fibonacci(n):
if n == 1 or n == 2:
return 1
else:
total = fibonacci(n-1) + fibonacci(n-2)
return total
if __name__ == '__main__':
for i in xrange(1, 11):
print fibonacci(i)
11–15.递归。
从写练习6-5 的解,用递归向后打印一个字符串。用递归向前以及向后打印一个字符串。
def forward(string):
if len(string) > 0:
print string[0]
forward(string[1:])
def backward(string):
if len(string) > 0:
backward(string[1:])
print string[0]
if __name__ == '__main__':
forward('12345678')
backward('12345678')