这些高级的函数大多数情况下可选的,但是在使用得当的情况下,它们能够简化编程。
匿名函数:lambda
表达式:
lambda arg1,arg2,...argN : expressing using arguments
lambda的主体是一个单个的表达式,而不是代码块,你仅能够在lambda主体中封装有限的逻辑进去,连if都无法使用,
这是有意设计的--它限制了程序嵌套。
例子:
>>> def func(x, y, z): return x+y+z
>>> func(2,3,4)
9
>>> f = lambda x,y,z: x+ y+ z
>>> f(2, 3, 4)
9
当函数不会在其他地方使用到时,灵活运用lambda能减少大量的代码,同时请尽量不要让python代码变的晦涩难懂。
在序列中映射函数:map
程序对列表和其他序列常常要对灭一个元素进行一个操作并把其结果集合起来,一般情况下我们通过一个for循环来实现。
实际上python提供了一个内置工具map函数,它会对以个序列对象中的没一个元素应用被传入的函数,并且返回一个包含了所有函数调用结果的列表。
例子:
>>> def inc(x): return x+ 10
>>> counters = [1,2,3,4]
>>> map(inc, counters)
[11, 12, 13, 14]
>>>
上面的例子也可以使用lambda更加简化:
>>> map((lambda x: x + 10), counters)
[11, 12, 13, 14]
因为map是内置函数,它还有一些性能方面的优势(简而言之,它要比自己编写的for循环更快)
此外,map还有比这里介绍更更高级的用法。
例如,提供了多个序列作为参数,它能够并行返回分别以美国序列中的元素作为函数对应参数得到的结果的列表。
>>> pow(3,4)
81
>>> map(pow,[1,2,3],[2,3,4])
[1, 8, 81]
函数式编程工具: filter和reduce
函数式编程的意思就是对序列应用一些函数的工具,map函数是这类工具中最简单的函数代表。
例如,基于某一测试函数过滤出一些元素(filter),以及对没对元素都应用函数并运行到最后结果(reduce)。
例如,下面这个filter调用实现从一个序列中挑选出大于5的元素。
>>> range(-5, 5)
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
>>> filter((lambda x:x > 0), range(-5,5))
[1, 2, 3, 4]
序列中的元素若其返回值为真的话,将被键入到结果的列表中。
下面是两个reduce的调用,计算了再一个列表中所有元素加起来的和以及乘积
>>> reduce((lambda x,y: x + y),[1,2,3,4])
10
>>> reduce((lambda x,y: x * y),[1,2,3,4])
24
每一步,reduce传递了当前的和或乘积以及下一个列表中的元素,传递给lambda函数。默认,系列中的第一个元素初始化了起始值。
列表解析:映射
列表解析基础
举例说明,python内置函数ord会返回一个字符的ASCII证书编码(chr内置函数是它的逆过程)
我们分别用for循环、map以及劫镖解析处理一段字符串
>>> ord('s')
115
>>> res = []
>>> for x in 'spam': res.append(ord(x))
>>> res
[115, 112, 97, 109]
>>> res = map(ord, 'spam')
>>> res
[115, 112, 97, 109]
>>> res = [ord(x) for x in 'spam']
>>> res
[115, 112, 97, 109]
列表解析在一个序列的值上应用一个任意表达式,将其结果手机到一个新的列表中并返回。
从语法上来说,列表解析是由方括号封装起来的。
增加测试盒嵌套循环
列表解析深圳要比现在所介绍的更通用。例如,能够在for之后编写一个if分支,用来增加选择逻辑。
举一个收集从0到9的偶素的平方,分别用列表解析,map和for循环
>>> [x ** 2 for x in range(10) if x%2 == 0]
[0, 4, 16, 36, 64]
>>> map((lambda x: x**2),filter((lambda x:x % 2 == 0),range(10)))
[0, 4, 16, 36, 64]
>>> res = []
>>> for x in range(10):
if x % 2 == 0:
res.append(x**2)
>>> res
[0, 4, 16, 36, 64]
实际上,列表解析还能更加通用。你可以再一个列表解析中编写任意数量的嵌套的for循环,并且每一个都有可选的关联的if测试。
[ expression for target1 in sequence1 [if condition]
for target2 in sequence2 [if condition]...
for targetN in sequenceN [if condition] ]
当for分支嵌套在列表解析中时,它们工作起来就像等效的嵌套的for循环语句。例如,
>>> res = [ x+ y for x in [0,1,2] for y in [100,200,300]]
>>> res
[100, 200, 300, 101, 201, 301, 102, 202, 302]
>>> res = []
>>> for x in [0,1,2]:
这些高级的函数大多数情况下可选的,但是在使用得当的情况下,它们能够简化编程。
匿名函数:lambda
表达式:
lambda arg1,arg2,...argN : expressing using arguments
lambda的主体是一个单个的表达式,而不是代码块,你仅能够在lambda主体中封装有限的逻辑进去,连if都无法使用,
这是有意设计的--它限制了程序嵌套。
例子:
>>> def func(x, y, z): return x+y+z
>>> func(2,3,4)
9
>>> f = lambda x,y,z: x+ y+ z
>>> f(2, 3, 4)
9
当函数不会在其他地方使用到时,灵活运用lambda能减少大量的代码,同时请尽量不要让python代码变的晦涩难懂。
在序列中映射函数:map
程序对列表和其他序列常常要对灭一个元素进行一个操作并把其结果集合起来,一般情况下我们通过一个for循环来实现。
实际上python提供了一个内置工具map函数,它会对以个序列对象中的没一个元素应用被传入的函数,并且返回一个包含了所有函数调用结果的列表。
例子:
>>> def inc(x): return x+ 10
>>> counters = [1,2,3,4]
>>> map(inc, counters)
[11, 12, 13, 14]
>>>
上面的例子也可以使用lambda更加简化:
>>> map((lambda x: x + 10), counters)
[11, 12, 13, 14]
因为map是内置函数,它还有一些性能方面的优势(简而言之,它要比自己编写的for循环更快)
此外,map还有比这里介绍更更高级的用法。
例如,提供了多个序列作为参数,它能够并行返回分别以美国序列中的元素作为函数对应参数得到的结果的列表。
>>> pow(3,4)
81
>>> map(pow,[1,2,3],[2,3,4])
[1, 8, 81]
函数式编程工具: filter和reduce
函数式编程的意思就是对序列应用一些函数的工具,map函数是这类工具中最简单的函数代表。
例如,基于某一测试函数过滤出一些元素(filter),以及对没对元素都应用函数并运行到最后结果(reduce)。
例如,下面这个filter调用实现从一个序列中挑选出大于5的元素。
>>> range(-5, 5)
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
>>> filter((lambda x:x > 0), range(-5,5))
[1, 2, 3, 4]
序列中的元素若其返回值为真的话,将被键入到结果的列表中。
下面是两个reduce的调用,计算了再一个列表中所有元素加起来的和以及乘积
>>> reduce((lambda x,y: x + y),[1,2,3,4])
10
>>> reduce((lambda x,y: x * y),[1,2,3,4])
24
每一步,reduce传递了当前的和或乘积以及下一个列表中的元素,传递给lambda函数。默认,系列中的第一个元素初始化了起始值。
列表解析:映射
列表解析基础
举例说明,python内置函数ord会返回一个字符的ASCII证书编码(chr内置函数是它的逆过程)
我们分别用for循环、map以及劫镖解析处理一段字符串
>>> ord('s')
115
>>> res = []
>>> for x in 'spam': res.append(ord(x))
>>> res
[115, 112, 97, 109]
>>> res = map(ord, 'spam')
>>> res
[115, 112, 97, 109]
>>> res = [ord(x) for x in 'spam']
>>> res
[115, 112, 97, 109]
列表解析在一个序列的值上应用一个任意表达式,将其结果手机到一个新的列表中并返回。
从语法上来说,列表解析是由方括号封装起来的。
增加测试盒嵌套循环
列表解析深圳要比现在所介绍的更通用。例如,能够在for之后编写一个if分支,用来增加选择逻辑。
举一个收集从0到9的偶素的平方,分别用列表解析,map和for循环
>>> [x ** 2 for x in range(10) if x%2 == 0]
[0, 4, 16, 36, 64]
>>> map((lambda x: x**2),filter((lambda x:x % 2 == 0),range(10)))
[0, 4, 16, 36, 64]
>>> res = []
>>> for x in range(10):
if x % 2 == 0:
res.append(x**2)
>>> res
[0, 4, 16, 36, 64]
实际上,列表解析还能更加通用。你可以再一个列表解析中编写任意数量的嵌套的for循环,并且每一个都有可选的关联的if测试。
[ expression for target1 in sequence1 [if condition]
for target2 in sequence2 [if condition]...
for targetN in sequenceN [if condition] ]
当for分支嵌套在列表解析中时,它们工作起来就像等效的嵌套的for循环语句。例如,
>>> res = [ x+ y for x in [0,1,2] for y in [100,200,300]]
>>> res
[100, 200, 300, 101, 201, 301, 102, 202, 302]
>>> res = []
>>> for x in [0,1,2]:
for y in [100,200,300]:
res.append(x+y)
>>> res
[100, 200, 300, 101, 201, 301, 102, 202, 302]
这里有个复杂得多的列表解析工具,表明了再嵌套的for从句中附加if选择的作用。
>>> [(x,y) for x in range(5) if x%2 == 0 for y in range(5) if y % 2 == 1]
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
如果用for和if嵌套则复杂的多。
列表解析和矩阵
举例说明劫镖解析处理矩阵的好处
下面的两段代码创建了一个单层的列表,其中包含了矩阵对元素的乘积。
>>> [M[row][col] * N[row][col] for row in range(3) for col in range(3)]
[2, 4, 6, 12, 15, 18, 28, 32, 36]
>>> [[M[row][col] * N[row][col] for col in range(3)] for row in range(3)]
[[2, 4, 6], [12, 15, 18], [28, 32, 36]]
最后一个表达式有效,因为row迭代是外层循环:对于每个row,它运行嵌套的列的迭代来创建矩阵每一行的结果。
可以用for循环简化,便于理解:
>>> res =[]
>>> for row in range(3):
tmp = []
for col in range(3):
tmp.append(M[row][col] * N[row][col])
res.append(tmp)
>>> res
[[2, 4, 6], [12, 15, 18], [28, 32, 36]]
对比这些语句就知道列表解析的好处,而且对于大型矩阵来说,运行速度相当快。
基于对运行在当前python下的测试,map调用比等效的for循环要快两倍,二列表解析常常比map调用要稍快一点。
这种速度上的差距来自于底层实现,map和列表解析是在解释器中以C语言的速度来运行的,比python的for在PVM中进步运行要快的多。
当然我们应该尝试让map调用和列表解析保持简单,对于更复杂的任务,用完整的语句来替代。
这里介绍两个在实际应用中更现实的列表和map的例子。回顾文件的readlines方法将返回以换行符\n结束的行,如果不想要换行符,
可以使用列表解析和map调用通过一个步骤从所有的行中将他们都去掉。
>>> open('myfile').readlines()
['aaa\n', 'bbb\n', 'ccc\n']
>>> [line.rstrip() for line in open('myfile').readlines()]
['aaa', 'bbb', 'ccc']
>>> [line.rstrip() for line in open('myfile')]
['aaa', 'bbb', 'ccc']
>>> map((lambda line:line.rstrip()),open('myfile'))
['aaa', 'bbb', 'ccc']
这里最后两个使用了文件迭代器(这里实际上是指不需要一个方法调用就能够在迭代中获取所有的行)。
另外一个例子,列表解析还能作为一种列选择操作来使用。python的标准SQL数据库API将返回查询结果保存为与下边类似的元组的列表:
列表就是表,二元组是行,元组中的元素就是列的值:
>>> listoftuple= [('bob', 35, 'mgr'), ('mel', 40, 'dev')]
>>> [age for (name, age, job) in listoftuple]
[35, 40]
>>> map((lambda (name, age, job): age), listoftuple)
[35, 40]