python基础学习(二)---函数
2018-01-09 23:25
357 查看
函数的定义
函数的调用和参数
函数的参数
位置参数
默认参数
可变参数
关键字参数
参数组合
高阶函数
mapreduce
filter
sorted排序
返回函数
匿名函数
偏函数
如果想定义一个空函数,则在函数体中使用
Python传入的参数分为四种,
上述函数的输入参数其实是一个tuple,使用可变参数后,在
如果想限定传入关键字参数的内容,可以使用命名关键字参数
map中传入的第一个参数是一个函数
在reduce函数中,传入的第一个参数也是函数
另一个filter的应用是生成指定范围的素数,使用埃式筛法,比如500以内的素数,1和2是素数,从2开始,将把2以后所有的数除以2,如果余数为0的那么就不是素数,将他们从序列中移除,然后对保留序列的下一个值3再进行一次过滤,随后的数字可以被3整除的都不是素数,将他们从序列中移除,这样依次类推直到序列最后一个数字。注意这里使用的是python3,python2.7无法运行。
作为一个高阶函数,
字符串也可以进行排序,排序规则是按照首字母的ASCII进行排序,也可以传入函数,将字符串按照处理后的结果进行排序。
如果需要降序排列,则将关键字
注意到,
但是在使用闭包时需要注意,由于返回函数时在执行时才被计算,所以在变量获取返回函数时,实际上获取的是一系列的函数和变量,所以如果函数内部产生多个返回函数,并将这些函数赋给多个变量,需要注意函数内变量的最终输出,是在所有返回函数都被输出的时候。
可以看到,这里所有的输出都是2,而不是预计中的0,1,2,这是因为在执行的时候,三个函数的参数
在使用返回函数,特别是返回多个函数时,需要特别注意这一点。
在之前的内容有很多地方都运用了匿名函数
可以看到指定
函数的调用和参数
函数的参数
位置参数
默认参数
可变参数
关键字参数
参数组合
高阶函数
mapreduce
filter
sorted排序
返回函数
匿名函数
偏函数
函数的定义
在Python中,使用def来定义一个函数,如下:def my_max(x, y): if x > y: return x else: return y
如果想定义一个空函数,则在函数体中使用
pass语句即可。
函数的调用和参数
Python的函数在调用时可以返回不只一个结果,默认的结果都保存在一个tuple中直接返回,可以使用多个参数按照顺序接受数据,也可以使用一个参数直接接受整个tuple。def my_max_min(x, y): if x > y: return x,y else: return y,x b = my_max_min(11,22) print(b) ---------- 输出打印 (22, 11)
Python传入的参数分为四种,
函数的参数
位置参数
位置参数就是一般我们常见的python函数的传参方式,按照一定的顺序写入参数,def my_max(x, y): if x > y: return x else: return y
默认参数
但是在一些情况下,特别是面向对象编程时,函数的一些参数一般使用的都是一样的值或是默认值,则是,如果在每次调用函数时都需要再写一遍的话,就会造成冗余或代码不整洁,此时可以使用默认参数,将默认的参数或重复使用的参数直接写入函数中,在调用时无需直接指定,也可以强制改变为别的值。#!/usr/bin/python # -*- encoding:utf-8 -*- def great_than(x, y = 100): if x > y: print("%d great_than %d" % (x,y)) else: print("%d less than %d" % (x,y)) great_than(200) great_than(30) ------ 输出: 200 great_than 100 30 less than 100 30 less than 50
可变参数
可变参数允许函数传入参数的数目是可变的,可以是1个,2个甚至是0个。一般在输入多个参数时,要么使用位置参数指定个数,要么使用list或tuple来将参数打包传入,但是这样都会比较繁琐,使用可变参数可以不受限制的将任意多个参数传入函数,当然在取用时,函数需要知道传入可变参数的格式或规律。#!/usr/bin/python # -*- encoding:utf-8 -*- def my_sum(numbers): sum = 0 for x in numbers: sum = sum + x return sum a = my_sum((1,2,3,4,5,6,67)) print("get %d" % a)
上述函数的输入参数其实是一个tuple,使用可变参数后,在
number前加
*,即可使用可变参数,调用时直接输入函数,无需在组合成tuple或list再输入。其实可变参数只是将输入的多个参数,自动的组合成一个tuple,然后在函数内使用。
#!/usr/bin/python # -*- encoding:utf-8 -*- def my_sum(*numbers): sum = 0 for x in numbers: sum = sum + x return sum a = my_sum(1,2,3,4,5,6,67) print("get %d" % a)
关键字参数
与可变参数不同,关键字参数允许传入0个或任意个含参数名的参数,这些参数在函数中自动组合成一个dict供使用。关键字参数在参数名前面加**来表示,如
def human(name, age, **kw)在函数中通过
if x in kw语句来检查传入的关键字参数是否有想要的值。
def human(name, age, **kw): print("name:%s" % name) print("age:%d" % age) if 'city' in kw: print("city:%s" % kw['city']) if 'job' in kw: print("job:%s" % kw['job']) human('lisa', 23, city='L.A', job='teacher')
如果想限定传入关键字参数的内容,可以使用命名关键字参数
def human(name, age, *, city, job):,注意,这种用法只能在python3中使用,python2.7并不支持。而如果列表中已经有一个可变参数,那么后面的关键字参数就不需要加
*了。
#!/usr/bin/python # -*- encoding:utf-8 -*- def human2(name, age, *, city, job): print("name:%s" % name) print("age:%d" % age) print("city:%s" % city) print("job:%s" % job) human2('lisa', 23, city='L.A', job='teacher') ———————————————————————— 输出: name:lisa age:23 city:L.A job:teacher
参数组合
以上四种参数类型可以在函数中同时调用,但是必须按照位置参数、默认参数、可变参数、命令关键字参数和关键字参数的顺序调用,python解释器会将传入的参数按照顺序填入函数中,并进行解析,def human(name, age, country="China", *argv, city, job, **kw)。
高阶函数
在python中,函数也可以作为参数传入另一个函数中,这样使用函数作为参数的函数就被称为高阶函数。函数也可以使用一个变量指向它,然后在之后的使用中,就可以使用该变量代替该函数的使用def abs_sum(x, y, f): return f(x) + f(y) f = abs a = abs_sum(-10, -20, f) print("abs_sum:%d" % a)
map/reduce
python内建了一些高阶函数,其中就有大名鼎鼎的map和
reduce,他们的都传入两个参数,
map中传入的第一个参数是一个函数
func,该函数只传入一个参数,第二个参数是一个Iterable的序列,然后返回一个
Iterator,
map函数的作用是将函数
func依次作用到序列的每个值,并将结果作为
Iterator打包返回,比如使用
map实现一些特殊规律的
list
>>> map(lambda x:x*x+x, range(10)) [0, 2, 6, 12, 20, 30, 42, 56, 72, 90]
在reduce函数中,传入的第一个参数也是函数
func,但是该函数必须传入两个参数,第二个参数也是一个Iterable的序列,结果也是返回一个结果,该结果类型取决于hunc函数的返回类型,
reduce首先将函数
func作用与序列的前两个元素,再继续作用于上一步得到的结果和第三个元素,依此类推,直到序列全部的都被计算过,形象点的看有点像贪吃蛇,以典型的高阶函数来写就是
f(f(f(f(x1,x2),x3),x4),x5)层层嵌套的函数执行。reduce简单的应用可以实现累加、str2num的转换等函数,而且只需要简单的代码即可实现
>>> a [1, 2, 3, 6, 4, 3, 1] >>> reduce(lambda x, y: str(x) + str(y), a) '1236431'
filter
filter函数对序列的传入参数和处理过程与map一致,但是有两点不同,首先,filter根据func处理该元素的返回值决定是否保留该元素(为True则保留,为False则移除),而不是直接保留
func的返回值,其次,根据上一步的要求,
filter返回的值就是对序列进行过滤指定的序列,类似于原始序列的子序列,而不是得到一个新的序列,虽然在内存上来说这是一个新的序列。下面的例子过滤掉序列中的偶数,保留奇数。
>>> a [1, 2, 3, 6, 4, 3, 1] >>> filter(lambda x:x%2, a) [1, 3, 3, 1]
另一个filter的应用是生成指定范围的素数,使用埃式筛法,比如500以内的素数,1和2是素数,从2开始,将把2以后所有的数除以2,如果余数为0的那么就不是素数,将他们从序列中移除,然后对保留序列的下一个值3再进行一次过滤,随后的数字可以被3整除的都不是素数,将他们从序列中移除,这样依次类推直到序列最后一个数字。注意这里使用的是python3,python2.7无法运行。
#!/usr/bin/python3 # -*- encoding:utf-8 -*- def ori(): n = 1 while True: n = n + 2 yield n def _not_div(n): return lambda x: x % n >0 def get_sushu(): it = ori() while True: n = next(it) yield n it = filter(_not_div(n), it) g = get_sushu() for n in g: if n < 50: print(n) else: break
sorted排序
sorted默认会将序列的元素按照升序排列,并输出一个新的序列。>>> sorted([1, 4, -2, 3, -23, 45]) [-23, -2, 1, 3, 4, 45]
作为一个高阶函数,
sorted也可以接收一个函数作为传入参数,通过一个
key传入,接下来会将传入的函数依次作用给各个元素,并按照作用后的结果对元素进行排序,如下是将数字按照绝对值大小进行排序。
>>> sorted([1, 4, -2, 3, -23, 45], key=abs) [1, -2, 3, 4, -23, 45]
字符串也可以进行排序,排序规则是按照首字母的ASCII进行排序,也可以传入函数,将字符串按照处理后的结果进行排序。
>>> sorted(['Apple', 'banana', 'dog', 'Fly']) ['Apple', 'Fly', 'banana', 'dog'] >>> import string >>> sorted(['Apple', 'banana', 'dog', 'Fly'], key=string.lower) ['Apple', 'banana', 'dog', 'Fly']
如果需要降序排列,则将关键字
reverse设为
True
>>> sorted(['Apple', 'banana', 'dog', 'Fly'], key=string.lower, reverse=True) ['Fly', 'dog', 'banana', 'Apple']
返回函数
既然一个函数可以作为参数传入另一个函数中,那么一个函数也可以作为一个函数的返回值,传递给函数外的变量。这里的返回函数与直接将一个变量指向函数有很大不同,f = abs这种其实只是创造了一个
abs函数指针的副本,返回函数的情况如下:
#!/usr/bin/python # -*- encoding:utf-8 -*- def lazy_multi(*argv): def multi(): m = 1 for n in argv: m = m * n return m return multi f1 = lazy_multi(1,2,3,4,5) print(f1) print(f1()) f2 = lazy_multi(2,4,6,8) print(f2) print(f2()) ———————————————————— 输出: <function multi at 0x7f95fe2cf668> 120 <function multi at 0x7f95fe2cf6e0> 384
注意到,
f1获取返回函数后,不会立即执行,所以
print(f1)只打印出了f的类型和指针地址,只有使用
f1()时,函数才真的执行并返回结果,这一特性。而且
f1和
f2的内容互相不会干扰,各自参数的作用域只在各自的
lazy_multi中,而各自执行的参数和返回值都保存在各自的返回函数中,这种特性被称为闭包(Closure)。
但是在使用闭包时需要注意,由于返回函数时在执行时才被计算,所以在变量获取返回函数时,实际上获取的是一系列的函数和变量,所以如果函数内部产生多个返回函数,并将这些函数赋给多个变量,需要注意函数内变量的最终输出,是在所有返回函数都被输出的时候。
#!/usr/bin/python # -*- encoding:utf-8 -*- def foo(): fs = [] for n in range(3): def ff(): return n fs.append(ff) return fs f1,f2,f3 = foo() print(f1) print(f1()) print(f2) print(f2()) print(f3) print(f3()) ———————————————————————— 输出: <function ff at 0x7f455959f758> 2 <function ff at 0x7f455959f7d0> 2 <function ff at 0x7f455959f848> 2
可以看到,这里所有的输出都是2,而不是预计中的0,1,2,这是因为在执行的时候,三个函数的参数
n都是执行到最后
f3的时候的值。这里可以使用两层嵌套函数,将
n的值准确的传递到内层函数,这样在执行的时候,内层函数的变量就不会随着代码逻辑自然改变。
def foo(): fs = [] def f_out(n): def ff(): return n return ff for n in range(3): fs.append(f_out(n)) return fs f1,f2,f3 = foo() print(f1) print(f1()) print(f2) print(f2()) print(f3) print(f3()) —————————————————————— 输出: <function ff at 0x7feb7ce437d0> 0 <function ff at 0x7feb7ce43848> 1 <function ff at 0x7feb7ce438c0> 2
在使用返回函数,特别是返回多个函数时,需要特别注意这一点。
匿名函数
在执行简单运算时,如果不想要麻烦的单独写一个函数,就可以使用匿名函数lambda,直接使用表达式作为一个函数使用,这样的好处首先是不需要额外的动作去新建函数,代码很简洁,其次是不需要指定函数名,这在一些复杂的应用中可以避免函数名的重复。
在之前的内容有很多地方都运用了匿名函数
lambda,它的基本格式是
lambda values:statement [condition1 [condition2 ..]],
lambda表达式之后紧跟着变量名,变量可以是一个或多个变量,随后是
:分隔符,之后是需要执行的语句
statement,最后是语句执行的条件或循环范围,如
for循环或
if条件语句,整体结构和
for循环一致,所以执行的顺序是,首先执行
for循环,然后执行
if等条件语句,最后执行
statement,并返回值。
lambda也是一个函数,所以可以使用变量直接指向它,获取的数据类型是一个
function。
>>> f = lambda x:x * x * x >>> f <function <lambda> at 0x7fe5eb4a3668> >>> f(10) 1000
偏函数
在介绍默认函数时,我们可以使用默认参数来设置函数执行时的默认变量,降低函数调用时的复杂度和难度,在一些内置函数中其实也有默认参数,在使用时可以通过指定内置函数的默认参数实现不同的函数功能。>>> int('100') 100 >>> int('100', base=2) 4 >>> int('10000', base=2) 16
可以看到指定
base=2之后,
int函数会对传入的
str数字字符串做二进制转换
int类型。但是在重复调用时,如果每次都要指定
base也比较麻烦,所以python提供了一个
functools模块,其中的偏函数(partiial)功能,就可以指定一个函数的默认参数并固化下来,变成一个新的函数,这样一个函数就可以方便的衍生出很多不同功能的函数,大大提高了代码的复用率和coding的效率。
>>> import functools >>> int('10000') 10000 >>> int8 = functools.partial(int, base=8) >>> int8('10000') 4096
相关文章推荐
- Python学习入门基础教程(learning Python)--2.1 Python下自定义函数 .
- python基础学习-3(函数)
- 函数:内嵌函数和闭包 - 零基础入门学习Python020
- 函数名function是一个数据类型,可以赋值 分类: python基础学习 2013-09-12 11:01 366人阅读 评论(0) 收藏
- python常用函数总结 分类: python基础学习 2014-02-07 14:12 260人阅读 评论(0) 收藏
- Python学习入门基础教程(learning Python)--2.3.1 Python传参函数设计
- Python学习入门基础教程(learning Python)--6.4 Python的list与函数
- .Net程序员之Python基础教程学习----函数和异常处理[Fifth Day]
- Python基础教程 第6章: 抽象(函数) 学习笔记
- Python基础函数学习笔记(一)
- Python学习基础之函数
- PYTHON基础学习之操作类的一些函数
- [Python学习] 专题一.函数的基础知识
- Python基础函数学习笔记(三)
- 深入学习Django源码基础2 - python多态技巧-运行时判断函数
- [Python学习] 专题一.函数的基础知识
- Python学习入门基础教程(learning Python)--8.3 字典常用的方法函数介绍
- [Python学习] 专题一.函数的基础知识
- Python学习入门基础教程(learning Python)--2 Python简单函数设计 .