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)
def max2(num1, num2):
return num1 if num1 > num2 else num2
def min2(num1, num2):
return num1 if num1 < num2 else num2
print max2(4,8)
print min2(4,8)
程序输出:
>>>
8
4
b)
def max2(num1, num2):
return num1 if num1 > num2 else num2
def min2(num1, num2):
return num1 if num1 < num2 else num2
def my_max(*args):
return reduce(max2, args)
def my_min(*args):
return reduce(min2, args)
print my_max(1,2,3,4,5,6,7,8)
print my_min(1,2,3,4,5,6,7,8)
程序输出:
>>>
8
1
11–4. 返回值。给你在5-13 的解创建一个补充函数。创建一个带以分为单位的总时间以及返回一个以小时和分为单位的等价的总时间。
"""将小时:分钟形式直接表示为分钟格式"""
def TranHourToMinute(strTime):
num = []
num = strTime.split(":")
return int(num[0]) * 60 + int(num[1])
def TranMinuteToHour(strTime):
hour,minute = divmod(strTime, 60)
return str(hour)+":"+str(minute)
if __name__ == "__main__":
while True:
strTime = raw_input("please enter the time,like 12:12(q to quit):")
if strTime.lower() == "q":
break
print "the time is:%d minutes" % (TranHourToMinute(strTime))
print "the same time is: %s" % (TranMinuteToHour(TranHourToMinute(strTime)))
程序输入输出:
>>>
please enter the time,like 12:12(q to quit):12:12
the time is:732 minutes
the same time is: 12:12
please enter the time,like 12:12(q to quit):q
11–6. 变长参数。下一个称为printf()的函数。有一个值参数,格式字符串。剩下的就是根据格式化字符串上的值,要显示在标准输出上的可变参数,格式化字符串中的值允许特别的字符串格式操作指示符,如%d, %f, etc。提示:解是很琐碎的----无需实现字符串操作符功能性,但你需要显示用字符串格式化操作(%)
这道题做出来很难,用python实现printf。
先放着
11–7. 用map() 进行函数式编程。给定一对同一大小的列表, 如[1 , 2 , 3] 和['abc','def','ghi',....],将两个标归并为一个由每个列表元素组成的元组的单一的表,以使我们的结果看起来像这样:{[(1, 'abc'), (2, 'def'), (3, 'ghi'), ...}.(虽然这问题在本质上和第六章的一个问题相似,那时两个解没有直接的联系)然后创建用zip 内建函数创建另一个解。
>>> map(lambda x, y:(x, y),[1,2,3],["abc","def","ghi"])
[(1, 'abc'), (2, 'def'), (3, 'ghi')]
>>> zip([1,2,3],["abc","def","ghi"])
[(1, 'abc'), (2, 'def'), (3, 'ghi')]
11–9. 用reduce()进行函数式编程。复习11.7.2 部分,阐述如何用reduce()数字集合的累加的代码。修改它,创建一个叫average()的函数来计算每个数字集合的简单的平均值。
def average(*args):
return reduce(lambda x, y: x + y, args) / len(args)
print average(1,2,3,4,5)
程序输出:
>>>
3
11–10.用filter()进行函数式编程。在unix 文件系统中,在每个文件夹或者目录中都有两个特别的文件:'.'表示现在的目录,'..'表示父目录。给出上面的知识,看下os.listdir()函数的文档并描述这段代码做了什么:files = filter(lambda x: x and x[0] != '.', os. listdir(folder))
将文件过滤出来。
11–11.用map()进行函数式编程。写一个使用文件名以及通过除去每行中所有排头和最尾的空白来“清洁“文件。在原始文件中读取然后写入一个新的文件,创建一个新的或者覆盖掉已存在的。给你的用户一个选择来决定执行哪一个。将你的解转换成使用列表解析。
这里直接用strip方法最简单,如果非要用map来进行过滤的话,需要自己编写类似strip的一个函数。
def strip(strTemp):
return strTemp.strip()
while True:
fileName = raw_input("please enter the fileName(q to quit):")
if fileName.lower() == "q":
break
choice = raw_input("n to new file, or c to cover file:")
if choice.lower() == "n":
newFileName = raw_input("please enter the new file name:")
with open(newFileName,"w") as fobj:
with open(fileName) as fobjold:
lines = fobjold.readlines()
for line in map(strip, lines):
fobj.write(repr(line))
fobj.write("\n")
else:
with open(fileName) as fobjold:
lines = fobjold.readlines()
with open(fileName,"w") as fobjold:
for line in map(strip, lines):
fobjold.write(repr(line))
fobjold.write("\n")
看了一下文件,结果正确。
11–12. 传递函数。给在这章中描述的testit()函数写一个姊妹函数。timeit()会带一个函数对象(和参数一起)以及计算出用了多少时间来执行这个函数,而不是测试执行时的错误。返回下面的状态:函数返回值,消耗的时间。你可以用time.clock()或者time.time(),无论哪一个给你提供了较高的精度。(一般的共识是在POSIX 上用time.time(),在win32 系统上用time.clock())注意:timeit()函数与timeit 模块不相关(在python2.3 中引入)
import time
def timeit(fun, *args):
time1 = time.clock()
for i in range(10000000):
fun(*args)
time2 = time.clock()
return time2 - time1
def fun(*args):
return reduce(lambda x, y:x + y, args)
if __name__ == "__main__":
usingTime = timeit(fun, 1,2,3,4,5,6,7,8,9,10)
print "using time is: %d" % usingTime
程序输出:
>>>
using time is: 19
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 mult(x, y):
return x * y
def fac1(n):
return reduce(mult, range(1,n))
def fac2(n):
return reduce(lambda x, y: x * y, range(1,n))
def timeit(fun, *args):
time1 = time.clock()
for i in range(1000000):
fun(*args)
time2 = time.clock()
return time2 - time1
print timeit(fac1, 10)
print timeit(fac2, 10)
程序输出:
>>>
2.41728863642
2.46803054498
11–14. 递归。我们也来看下在第八章中的Fibonacci 数字。重写你先前计算Fibonacci 数字的解(练习8-9)以便你可以使用递归。
def fib(num):
a,b = 1,1
while num - 1:
a,b = b,a + b
num -= 1
return a
def new_fib(num, a = 1, b = 1):
if num - 1:
a,b = b,a+b
return new_fib(num - 1, a, b)
else:
return a
print new_fib(8)
print fib(8)
不过这里递归用的好丑,但是也不知道该怎么弄好就是了。
11–15.递归。从写练习6-5 的解,用递归向后打印一个字符串。用递归向前以及向后打印一个字符串。
def printLeft(strTemp):
if strTemp:
print strTemp[0],
return printLeft(strTemp[1:])
def printRight(strTemp):
if strTemp:
print strTemp[-1],
return printRight(strTemp[:-1])
printLeft("hello world!")
print
printRight("hello world!")
程序输出:
>>>
h e l l o w o r l d !
! d l r o w o l l e h
11–17.定义
(a) 描述偏函数应用和currying 之间的区别。
(b) 偏函数应用和闭包之间有什么区别?
(c) 最后,迭代器和生成器是怎么区别开的?
个人感觉,偏函数就是lambda罢了。
然后迭代器和生成器的区别就是一个运行时候很顺利,一个运行时候会一卡一卡的。