python 函数进阶:参数传递,高阶函数,lambda 匿名函数,global 变量,递归
2018-03-27 10:09
1006 查看
python函数进阶:参数传递,高阶函数,lambda 匿名函数,global 变量,递归
函数是基本类型
在Python中,函数是一种基本类型的对象,这意味着可以将函数作为参数传给另一个函数
将函数作为字典的值储存
将函数作为另一个函数的返回值
In [1]:
def square(x): """Square of x.""" return x*x def cube(x): """Cube of x.""" return x*x*x作为字典的值:In [2]:
funcs = { 'square': square, 'cube': cube, }例子:In [3]:
x = 2 print square(x) print cube(x) for func in sorted(funcs): print func, funcs[func](x)
4 8 cube 8 square 4
函数参数
引用传递
Python中的函数传递方式是
call by reference即引用传递,例如,对于这样的用法:
x = [10, 11, 12] f(x)传递给函数
f的是一个指向
x所包含内容的引用,如果我们修改了这个引用所指向内容的值(例如
x[0]=999),那么外面的
x的值也会被改变。不过如果我们在函数中赋给
x一个新的值(例如另一个列表),那么在函数外面的
x的值不会改变:In [4]:
def mod_f(x): x[0] = 999 return x x = [1, 2, 3] print x print mod_f(x) print x
[1, 2, 3] [999, 2, 3] [999, 2, 3]In [5]:
def no_mod_f(x): x = [4, 5, 6] return x x = [1,2,3] print x print no_mod_f(x) print x
[1, 2, 3] [4, 5, 6] [1, 2, 3]
默认参数是可变的!
函数可以传递默认参数,默认参数的绑定发生在函数定义的时候,以后每次调用默认参数时都会使用同一个引用。这样的机制会导致这种情况的发生:In [6]:def f(x = []): x.append(1) return x理论上说,我们希望调用
f()时返回的是
[1], 但事实上:In [7]:
print f() print f() print f() print f(x = [9,9,9]) print f() print f()
[1] [1, 1] [1, 1, 1] [9, 9, 9, 1] [1, 1, 1, 1] [1, 1, 1, 1, 1]而我们希望看到的应该是这样:In [8]:
def f(x = None):
if x is None:
x = []
x.append(1)
return x
print f() print f() print f() print f(x = [9,9,9]) print f() print f()
[1] [1] [1] [9, 9, 9, 1] [1] [1]
高阶函数
以函数作为参数,或者返回一个函数的函数是高阶函数,常用的例子有map和
filter函数:
map(f, sq)函数将
f作用到
sq的每个元素上去,并返回结果组成的列表,相当于:
[f(s) for s in sq]In [9]:
map(square, range(5))Out[9]:
[0, 1, 4, 9, 16]
filter(f, sq)函数的作用相当于,对于
sq的每个元素
s,返回所有
f(s)为
True的
s组成的列表,相当于:
[s for s in sq if f(s)]In [10]:
def is_even(x): return x % 2 == 0 filter(is_even, range(5))Out[10]:
[0, 2, 4]一起使用:In [11]:
map(square, filter(is_even, range(5)))Out[11]:
[0, 4, 16]
reduce(f, sq)函数接受一个二元操作函数
f(x,y),并对于序列
sq每次合并两个元素:In [12]:
def my_add(x, y): return x + y reduce(my_add, [1,2,3,4,5])Out[12]:
15传入加法函数,相当于对序列求和。返回一个函数:In [13]:
def make_logger(target): def logger(data): with open(target, 'a') as f: f.write(data + '\n') return logger foo_logger = make_logger('foo.txt') foo_logger('Hello') foo_logger('World')In [14]:
!cat foo.txt
Hello WorldIn [15]:
import os os.remove('foo.txt')
匿名函数
在使用map,
filter,
reduce等函数的时候,为了方便,对一些简单的函数,我们通常使用匿名函数的方式进行处理,其基本形式是:
lambda <variables>: <expression>例如,我们可以将这个:In [16]:
print map(square, range(5))
[0, 1, 4, 9, 16]用匿名函数替换为:In [17]:
print map(lambda x: x * x, range(5))
[0, 1, 4, 9, 16]匿名函数虽然写起来比较方便(省去了定义函数的烦恼),但是有时候会比较难于阅读:In [18]:
s1 = reduce(lambda x, y: x+y, map(lambda x: x**2, range(1,10))) print(s1)
285当然,更简单地,我们可以写成这样:In [19]:
s2 = sum(x**2 for x in range(1, 10)) print s2
285
global 变量
一般来说,函数中是可以直接使用全局变量的值的:In [20]:x = 15 def print_x(): print x print_x()
15但是要在函数中修改全局变量的值,需要加上
global关键字:In [21]:
x = 15
def print_newx():
global x
x = 18
print x
print_newx()
print x
18 18如果不加上这句
global那么全局变量的值不会改变:In [22]:
x = 15
def print_newx():
x = 18
print x
print_newx()
print x
18
15
递归
递归是指函数在执行的过程中调用了本身,一般用于分治法,不过在Python中这样的用法十分地小,所以一般不怎么使用:Fibocacci 数列:In [23]:
def fib1(n): """Fib with recursion.""" # base case if n==0 or n==1: return 1 # recurssive caae else: return fib1(n-1) + fib1(n-2) print [fib1(i) for i in range(10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]一个更高效的非递归版本:In [24]:
def fib2(n): """Fib without recursion.""" a, b = 0, 1 for i in range(1, n+1): a, b = b, a+b return b print [fib2(i) for i in range(10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
相关文章推荐
- python进阶教程之函数参数的多种传递方法
- python进阶教程之函数参数的多种传递方法
- python进阶教程之函数参数的多种传递方法
- python学习笔记11(函数二): 参数的传递、变量的作用域
- Python 函数式编程(高阶函数、把函数作为参数、map()函数、reduce()函数、filter()函数、自定义排序函数、函数返回函数、闭包、匿名函数、装饰器decorator)
- Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- Python函数参数传递以及变量作用域
- python学习笔记12(函数三): 参数类型、递归、lambda函数
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- Matlab 函数进阶:使用匿名函数和内嵌函数处理多变量传递问题(Matlab 7.0以上)
- 018--python 函数参数、变量、前向引用、递归
- **Python的函数参数传递 和 global
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- Python的变量赋值及函数参数传递规则
- Python语言基础之函数的参数传递,lambda 表达式
- python进阶教程之函数参数的多种传递方法
- 一个函数调用另一个函数,最好用参数传递。不然就得声明为全局变量。被调用的函数里边,变量前面写 global
- <Python进阶读书笔记>之(一) 函数不定参数传递
- Matlab 函数进阶:使用匿名函数和内嵌函数处理多变量传递问题(Matlab 7.0以上)