Python学习之函数

和其他的一些编程语言一样,Python是一个拥有丰富函数的语言。函数在Python中是内建支持的一种封装,我们通过把大段代码拆成函数,函数就是面向过程的程序设计的基本单元。

而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

Python学习笔记
自定义高阶函数

高阶函数的概念就是一个函数可以接受普通的数据类型为参数也可以接受函数为参数,

那么定义一个函数,作用是出入两个参数,通过第三个函数参数进行一些运算,并返回
def add(x, y, f):
    return f(x) + f(y)

如果f分别为取绝对值,求平方根
add(-5, 9, abs)
add(25, 9 ,math.sqrt)

返回的结果为
14
8

这里需要注意的是由于使用了运算函数,因此要导入运算相关的库
import math


map()函数

map()函数是Python内置的高阶函数:map(fun,list) ->list

接受一个函数func和一个数组list,而func的作用就是依次作用在list的每个元素上,得到一个新的list并返回。
def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

输出结果:

[1, 4, 9, 10, 25, 36, 49, 64, 81]

如果list是一个字符串数组,那么可以通过list[0]获得到字符串的第一个字符,list[1:]获得到字符串第二个以及之后的所有字符。举个例子,将一个list中的名字按照首字符大写以后小写进行输出。

def reName(name):
    return name[0].upper() + name[1:].lower()

print map(reName, [‘adam’,’LISA’,’RoCky’,’tIm'])

输出结果为:
[‘Adam’,’Lisa’,’Rocky’,’Tim’]


reduce()函数
reduce()函数是Python内置的高阶函数:reduce(func,list) ->id

reduce()函数中的func必须接受两个参数,redure()对list中的每个元素反复调用func,并返回结果。

例如编写一个函数:
def func(x, y):
    return x + y

在调用reduce(func,[1,3,5,7,9])的时候,其实内部做的是这样的计算:
先计算头两个元素:f(1, 3),结果为4;
再把结果和第3个元素计算:f(4, 5),结果为9;
再把结果和第4个元素计算:f(9, 7),结果为16;
再把结果和第5个元素计算:f(16, 9),结果为25;
由于没有更多的元素了,计算结束,返回结果25。

reduce()函数还可以接受三个参数,第三个参数是可选的,作为计算的初始值,如果改为
reduce(f, [1, 3, 5, 7, 9], 100)
返回的结果就会是125,因为开始的时候进行的是func(100,1)

虽然Python内置的有求和的sum()函数,但是没有求积的函数,那么自己写个。函数体func如下:
def prod(x,y):
     return x * y

print reduce(prod,[2,4,5,7,12])

输出结果为
3360


filter()函数

filter()函数也是Python内置的一个高阶函数:filter(func,list) ->list

filter()函数中的func函数的作用是对每个元素进行判断并返回Ture或者False,然后filter()函数会根据返回结果过滤掉不符合条件的元素,并返回一个新的符合条件的list。

例如使用filter()函数进行list的奇偶过滤:
def is_odd(x):
     return x % 2 == 1

filter(is_odd,[1,4,6,7,9,12,17])

然后返回结果为
[1, 7, 9,17]


还比如删除list中的None或者🈳字符串
def is_not_empty(s):
     return s and len(s.strip()) > 0

filter(is_not_empty,[’test’,None,’’,’str’,’  ‘,’END'])

返回结果为
[’test’,’str’,’END']

s.strip(rm)的意思是删除s字符串开头、结尾处为rm序列的字符,当rn为空的时候,默认删除空白符(‘\n’,’\r’,’\t’,'')

sorted()函数

sorted()函数是一个Python内置的高阶函数:sorted(list) ->list

storted()函数可以自定义排序规则,不单单是升序排序。他可以接受一个比较函数实现自定义排序,比较函数的定义是,传入两个待比较元素x和y,如果x应该排在y前面,返回-1(降序),如果x应该排在y后面,返回1(升序),如果x和y相等,返回0。

一个倒序函数如下
def reversed_cmp(x, y):
    if x > y:
        return -1
    if x < y:
        return 1
    return 0

同时sorted()函数还可以对字符串进行排序,字符串默认按照ASCII大小来比较,大写字母的ASCII比小写字母的ASCII小,排在前面。


类型检验--isinstance()

其实在进行初期的Python学习的时候,对输入的判断一直没有进行类型判断,作为一个软件开发人员来说,这是不严谨的编程方法,现在就来介绍一个类型检验的函数:isinstance()

先举个栗子,求绝对值
def my_abs(x):
     if x >= 0:
          return x
     else:
          return -x

这里的x如果是字符类型或者非int、float类型就会报错,使用isinstance()函数可以这样做
def my_abs(x):
     if not is instance(x,(int,float)):
          raise TypeError(‘您输入的不是int、float类型')
     if x >= 0:
          return x
     else:
          return -x



可变参数的函数写法

# *符号允许传入的参数为可变的个数
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n
    return sum

打印如下,
print 'sum:',calc(1,2,3)
sum:6

# 同时如果你有一个list,也可以使用这样的方法进行list内数据的作为可变参数
numberList = [1,3,4]
print "sum:",calc(*numberList)
sum:8


关键字参数**kw

可变参数允许0或者任意个参数,这些参数会组装成一个元组(Tuple),而关键字参数则允许传入0个或者任意个含参数名的参数,这些参数在函数内部组装成一个字典(Dict),使用关键字kw
def person(name,age,**kw):
    print ('name:',name,'age:',age,'other',kw)

调用,
person('Rocky',24)
person('Rocky',24,city = 'beijing')
person('Rocky',24,city = 'beijing',job = 'Coder')

输出如下,
('name:', 'Rocky', 'age:', 24, 'other', {})
('name:', 'Rocky', 'age:', 24, 'other', {'city': 'beijing'})
('name:', 'Rocky', 'age:', 24, 'other', {'city': 'beijing', 'job': 'Coder'})

# 当然,如果正好有一个字典,可以这样传递参数
extra = {'city':'beijing','job':'coder'}
person('Rocky',24,**extra)
('name:', 'Rocky', 'age:', 24, 'other', {'city': 'beijing', 'job': 'coder'})


命名关键字参数*

如果要限制关键字参数的名字,可以使用命名关键字参数,定义方法为:
def person(name,age,*,city,job):
     print(name,age,city,job)

和关键字参数**kw不同的是,命名关键字参数需要一个特殊分隔符*,它之后的参数就是命名关键字参数。
更不便捷的一点是,明明关键字在使用的时候,必须把参数名带上,不能省略。但是如果命名关键字有默认值的时候,可以在调用函数的时候省略,
person(‘Rocky’,24,city = ‘beijing’,job = ‘coder')
# 正确

person(‘Rocky’,24,‘beijing’,‘coder')
# 错误

如果改变person函数的定义
def person(name,age,*,city = ‘beijing’,job):
     print(name,age,city,job)

现在调用函数的时候可以这样
person(‘Rocky’,24,job = ‘coder')


imooc廖雪峰Python学习