第六讲:函数(下)

函数(下)

一、lambda(参数,函数体)

 

1、函数说明:

  • lambda语句被用来创建新的函数对象,并且在运行时返回它们。
  • Python使用lambda关键字来创建匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
  • lambda只是一个表达式,函数体比def简单很多
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda函数拥有自己的名字空间,且不能访问自由参数列表之外后全局名字空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
  • lambda会返回一个函数对象,但这个对象不会赋给一个标识符,而def则会把函数对象赋值给一个变量(函数名)。
  • 像if或for或print等语句不能用于lambda中。
  • lambda函数不能共享给别的程序调用,def定义的函数可以

2、语法:

lambda函数的语法只包含一个语句,如下:

lambda [arg1 [, agr2,.....argn]] : expression
 
 
3、lambda与函数区别:
#示例1:
g=lambda x:x+1
print g(1)

#示例2:
add=lambda x,y:x+y
print add(2,4)

说明:lambda作为一个表达式,定义了一个匿名函数,x为入口参数,x+1为函数体,
用函数表达:
def g(x):
return x+1
print g(1)
 
 
练习1:用lambda函数实现字符串指定次数打印,数字与指定数字相乘
#方法一:
def make_repeater(n):
    return lambda s: s*n
twice = make_repeater(2)
print twice('word')
print twice(5)

#方法二:
data=lambda s,n:s*n
print data('hello',3)
print data(u'加油!',3)
print data(5,3)

 

 

二、map(函数,序列)

1、函数说明:

  • 将每个列表元素或字符串都执行某个函数
  • map的函数操作方法:它将每个字符串或者列表元素,应用某个函数方法,结果返回列表。
  • 当seq只有一个时,将函数func作用于这个seq的每个元素上,并得到一个新
  • 的seq。

 

2、单一seq序列

让我们来看一下只有一个seq的时候,map()函数是如何工作的。

从上图可以看出,函数func函数会作用于seq中的每个元素,得到func(seq[n])组成的列表
 

示例:

 >>> map(str,'123')
['1', '2', '3']
>>> map(int,'123')
[1, 2, 3]
>>> ''.join(map(str,[1,2,3,4]))
'1234'

 

 

3、多个seq序列

示例1:求两个数的和

r=map(lambda x,y:x+y,[2,3,4],[5,6,7])
print r

运行结果:
[7, 9, 11]

示例2:求两个数的和与差

r=map(lambda x,y:(x+y,y-x),[2,3,4],[5,6,7])
print r

运行结果:[(7, 3), (9, 3), (11, 3)]

 

 
4、map无法处理seq长度不一致、对应位置操作数类型不一致的情况,这两种情况都会报类型错误。
#当对应位置的数据类型不一致时:
res = map(lambda x , y : (x ** y, x + y), [2,4,6],[3,2,'a'])
print res

运行结果:
Traceback (most recent call last):
  File "E:/workplace/2019pratice/hanshu.py", line 132, in <module>
    res = map(lambda x , y : (x ** y, x + y), [2,4,6],[3,2,'a'])
  File "E:/workplace/2019pratice/hanshu.py", line 132, in <lambda>
    res = map(lambda x , y : (x ** y, x + y), [2,4,6],[3,2,'a'])
TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str'



#当多个序列的长度不一致时: r = map(lambda x , y : (x ** y, x + y),[2,4,6],[3,2,4,5]) print r
运行结果: Traceback (most recent call last): File
"E:/workplace/2019pratice/hanshu.py", line 137, in <module> [2,4,6],[3,2,4,5]) File "E:/workplace/2019pratice/hanshu.py", line 136, in <lambda> r = map(lambda x , y : (x ** y, x + y), TypeError: unsupported operand type(s) for ** or pow(): 'NoneType' and 'int'

 



三、filter(函数名,需过滤序列)

 函数说明:

filter()函数可以对序列做过滤处理,就是说可以使用一个自定的函数过滤一个序列,把序列的每一项传到自定义的过滤函数里处理,并返回结果做过滤。最终一次性返回过滤后的结果。

示例1:过滤列表中大于5小于10的数


def
guolvFunc(num): if num>5 and num<10: return num seq=(12,50,8,17,65,14,9,6,14,5) result=filter(guolvFunc,seq) print result

运行结果:
(8, 9, 6)

示例2:过滤1,到10内的所有素数 判断是否是素数:能被自己本身和1整除

import math
def getNum(n):
    check=int(math.sqrt(n))   #math.sqrt函数返回一个数的平方跟
    for i in range(2,check+1):
        if n%i==0:
            return None
    return n

ret=filter(getNum,range(1,10))
print ret

运行结果:
[1, 2, 3, 5, 7]

 

四、reduce(二元函数,序列)

函数说明:

reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:
用传给reduce中的函数 func()(必须是一个二元操作函数),先对集合中的第1,2个数据进行操作,得到的结果再与第3个数据用func()函数运算,最后得到一个结果。

示例:

#coding=utf-8
lst = [1,2,3,4,5]
print reduce(lambda x,y:x+y,lst)

 说明:这种方式用lambda表示当做参数,因为没有提供reduce的第三个参数,所以第一次执行时x=1,y=2,第二次x=1+2,y=3,即列表的第三个元素

方法二:

lst = [1,2,3,4,5]
print reduce(lambda x,y:x+y,lst,0) #0表示给x初始化值

 说明:

#这种方式用lambda表示当做参数,因为指定了reduce的第三个参数为0,所以第一次执行时x=0,y=1,第二次x=0+1,y=2,即列表的第二个元素, 假定指定reduce的第三个参数为100,那么第一次执行x=100,y仍然是遍历列表的元素,最后得到的结果为115

 

练习1:使用reduce()计算1~10000所有奇数的和

sum=reduce(lambda x,y:x+y,range(1,10001,2))
print sum

 

五、eval(字符串)-->表达式

函数说明:eval语句用来计算存储在字符串中的有效Python表达式,并返回计算结果。

示例1:

s='3+4*4'
result=eval(s)
print result

运行结果:
19

 示例2:

def printStr() :
print "hello world"
return 1
n = eval('printStr()')
print n

运行结果:
1

 

六、exec()与eval()的区别:

函数说明:

从上面exec和eval的讲解中,可以看出,他们都可以动态的执行存储在字符串或文本中的有效的Python表达式,那他们又有什么区别呢?
区别就是 :exec执行的Python语句没有返回值,而eval有返回值。
def printStr() :
    print "hello world"
    return 1
print u"***** eval 执行******"
print eval('printStr()')
print u"***** exec 执行******"
exec('printStr()') #加print 则报语法错误

运行结果:
***** eval 执行******
hello world
1
***** exec 执行******
hello world


 

七、range和 xrange 的区别

函数说明:

range会直接生成一个list对象;
xrange则不会直接生成一个list,而是每次调用返回其中的一个值【xrange返回的是一个生成器】

 

示例1:

for i in range(2):
    print i,
print
for j in xrange(3):
    print j,

运行结果:
0 1
0 1 2


 

示例2:有一个分数序列:2/1,3/2,5/3,8/5,13/8,21/13...,求这个数列的前20项之和。

#a,b=a+b,a
a=2.0 b=1.0 sum=0.0 for i in xrange(20): sum+=a/b a,b=a+b,a print sum

运行结果:
21

 

posted on 2019-05-28 00:08  Cwenky  阅读(238)  评论(0编辑  收藏  举报