Python 抽象(6) 持续更新
主要学习将语句组织成函数,告诉程序如何做事。
斐波那契数列 (Fibonacci) (任意一个数都是前面两个数之和的序列)
fibs = [0,1]; num = int(raw_input('Input Fibonacci numbers:')) for i in range(num - 2): fibs.append(fibs[-1] + fibs[-2]) print fibs
输出
C:\Users\ChengXu1\Desktop>python aa.py Input Fibonacci numbers:12 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
创建函数
def hello(name): print 'Hello',name hello('Zhao')
输出
C:\Users\ChengXu1\Desktop>python aa.py
Hello Zhao
函数是否可调用
>>> import math >>> callable(math.sqrt) True
在Python3.0中callable废弃了,用hasattr(object, name)代替。
hasattr 判断对象object是否包含名为name的特性。
>>> hasattr(list, 'append') True >>> hasattr(list, 'add') False
封装 斐波那契数列 函数
def fibs(num): result = [0,1]; for i in range(num - 2): result.append(result[-1] + result[-2]) return result print fibs(10) print fibs(13)
C:\Users\ChengXu1\Desktop>python aa.py [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
无返回值的函数
def fun(): print 'call 1' return print 'call 2' fun()
输出
C:\Users\ChengXu1\Desktop>python aa.py
call 1
函数内遇到 return 直接跳出函数。
函数参数
def语句中 函数括号里面的变量叫形参,调用函数提供的值叫实参。
当函数内部把参数重新赋值的时候,函数外部变量不会受到影响。
def change(num): num = 2 num = 1 change(num) print num
输出
C:\Users\ChengXu1\Desktop>python aa.py
1
下面的变量就会受到影响,因为它们并没有对函数参数赋值,而是对序列元素重新赋值。
def change(numbers): numbers[0] = -1 numbers = [1,2] change(numbers) print numbers
输出
C:\Users\ChengXu1\Desktop>python aa.py
[-1, 2]
想要避免出现修改,需要传进去 序列的副本 进去
def change(numbers): numbers[0] = -1 numbers = [1,2] change(numbers[:]) print numbers
输出
C:\Users\ChengXu1\Desktop>python aa.py
[1, 2]
判断两个序列是不是独立的,可以这样
>>> numbers = [1,2] >>> n = numbers[:] >>> n is numbers False
判断两个序列值是否相等
>>> numbers = [1,2] >>> n = numbers[:] >>> n == numbers True
关键字参数和默认值
上面使用的函数参数都位置参数,但是位置参数的顺序不容易记住,为了更加简单,使用参数名提供参数称为关键字参数。
def fun(greeting, name): print '%s %s' % (greeting, name) fun(name='Zhao', greeting='Hello')
输出
Hello Zhao
默认值
当函数参数有默认值时,调用的时候,可以提供函数参数,也可以不提供参数。
def fun(greeting='Hello', name='World'): print '%s %s' % (greeting, name) fun() fun(name='Zhao', greeting='Hello')
输出
Hello World
Hello Zhao
任意参数数量
有的时候需要定义一个类似像print函数一样,参数数量是不固定的,那么就可以这样定义参数。
def print_parameters(*parameters): print(parameters) print_parameters('1', '2', '3')
输出
('1', '2', '3')
星号的作用就是 收集其余的位置参数。
如果需要收集能收集关键字参数的操作,那么就需要两个星号。
def print_parameters(x,**parameters): print(x,parameters) print_parameters(x='1', y='2', z='3')
输出
('1', {'y': '2', 'z': '3'})
参数收集的逆过程
def add(x, y): return x + y parms = (1,2) print add(*parms) def print_parameters(x, **parameters): print(x, parameters) parameters = {'y': '2', 'z': '3'} print_parameters(x='1', **parameters)
输出
3 ('1', {'y': '2', 'z': '3'})
作用域
在执行类似x=1赋值语句后,名称x引用到值1,python实际上是 变量和所对应的值用的是一个字典保存的,可以用 vars函数返回这个字典。
x = 1 __dict = vars() print __dict['x'] __dict['x'] += 1 print x print __dict['x']
输出
1 2 2
这个字典叫做命名空间或者作用域。除了全局作用域,每次调用函数都会创建一个新的作用域。
def foo(): x = 99 print 'Function', x x = 1 foo() print 'Global', x
输出
Function 99
Global 1
当全局变量和局部变量,变量名相同时,全局变量就会被局部变量屏蔽,可以用globals函数获取全局变量值(locals返回局部变量的字典)。
def foo(): x = 99 print 'Function', x space = globals() # print 'globals', space # print locals() space['x'] = 88 print 'Global Function', space['x'] x = 1 foo() print 'Global', x
输出
Function 99 Global Function 88 Global 88
重新绑定全局变量
x = 1 def change_global(): global x x += 2 change_global() print x
输出
3
函数嵌套
def fun1(): def fun2(): print 'call fun2' fun2() fun1()
输出
call fun2
函数闭包
def fun1(): print 'call fun1' def fun2(): return 'call fun2' return fun2 print fun1()()
Python 3.0中,nonlocal关键字让户对外部作用域的变量进行赋值(不是全局作用域),使用方法和global关键字一样。
递归
三种实现的阶乘
def factorial(n): result = n for i in range(n - 1, 0, -1): result *= i return result # 36288000 print factorial(10) def factorial2(n): result = n for i in range(1, n): result *= i return result # 36288000 print factorial2(10) def factorial3(n): if n == 1: return 1 return n * factorial3(n - 1) print factorial3(10)
递归经典之 二分法查找
def search(a, m): lower = 0 high = len(a) - 1 while low <= high: mid = (low + high) / 2 midval = a[mid] if midval < m: low = mid + 1 elif midval > m: high = mid - 1 else: print mid return mid print -1 return -1 seq = [34, 67, 100, 200, 300, 95, 94] seq.sort() print seq print search(seq, 100) import bisect # 标准库中的二分法查找 print bisect.bisect(seq, 100)
bisect 是个非常有用的模块,主要是针对数组的插入及排序操作。
相关文档连接
http://www.jb51.net/article/55638.htm
http://www.cnblogs.com/skydesign/archive/2011/09/02/2163592.html
Python对于一些”函数式编程“方面的函数 map、filter和reduce函数(Python3.0都迁移到 functools 模块中)
map将序列种的元素全部传递给一个函数
>>> map(str,range(0,10)) ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
isalnum 判断字符是否为英文字母或数字
filter基于一个函数,进行对元素过滤。
def func(x): return x.isalnum() seq = ['%', '1', 'n'] print filter(func, seq)
还可以这样
seq = ['%', '1', 'n'] print [x for x in seq if x.isalnum()] # Lambda 表达式 匿名函数 print filter(lambda x: x.isalnum(), seq)
reduce函数 对sequence中的item顺序迭代调用function
>>> def add(x,y): return x + y >>> reduce(add, range(1, 11)) 55 >>> print reduce(lambda x, y : x + y,range(1,11) ) 55
print sum(range(1, 11))
apply函数
http://wangwei007.blog.51cto.com/68019/1157901

浙公网安备 33010602011771号