python学习笔记(六)
函数
有了语句我们可以做很多事,但是如果要编写大型或更复杂的程序,那么代码的重用性值得我们考虑,因此就有了函数,函数其实可以重复利用的代码块。回忆一下我们N年前用C++痛苦的编写一个斐波那契数列,现用python是多么容易的实现:
fibs = [ 0 , 1 ] num = input ( 'How much numbers do you want:' ) #注意这里是input,或者是int(raw_input("")),不然会出错 for i in range (num - 2 ): fibs.append(fibs[ - 2 ] + fibs[ - 1 ]) print fibs raw_input ( 'press any key to exit!' ) |
函数可以调用,它执行某种操作并且可能返回值,内建的callable函数(python3中无此函数)可以判断函数是否可以调用:
>>> import math >>> x=1 >>> y=math.sqrt >>> callable(x) False >>> callable(y) True
创建函数——用def关键字来定义
>>> def fibs(num): #创建函数 result=[0,1] for i in range(num-2): result.append(result[-2]+result[-1]) return result >>> fibs(10) #调用函数 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] >>> fibs(15) #调用函数 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
记录函数
要想给函数写文档让函数容易理解的话,除了写注释外还可以写文档字符串,它作为函数的一部分进行存储,并且可以调用查看:
>>> def square(x): 'caculate the square of the number x.' #插入文档字符串 return x*x >>> square.func_doc #访问文档字符串 'caculate the square of the number x.'
(__doc是函数属性,输入square.,然后按tab键,能看到所有的函数属性)
函数参数
函数的定义和调用都比较简单,但是函数的用法是体现在它的参数上的,这个比较复杂。
(1)、普通形参
>>> def printMax(a, b): if a > b: print a, 'is maximum' else: print b, 'is maximum' >>> printMax (5,3) 5 is maximum
(2)、默认参数值
>>> def say(message, times = 2): print message * times >>> say('hello') hellohello >>> say(4) 8
(3)、关键参数
>>> def func(a, b=5, c=10): print 'a is', a, 'and b is', b, 'and c is', c >>> func(4) a is 4 and b is 5 and c is 10
(4)、可变长度参数
1)、*非关键字可变长参数(元组)
>>> def tupleVarArgs(arg1, arg2 = "defaultB", *theRest): print 'arg 1:', arg1 print 'arg 2:', arg2 for eachXtrArg in theRest: print 'another arg:', eachXtrArg >>> tupleVarArgs('abc') arg 1: abc arg 2: defaultB >>> tupleVarArgs(45,67.8) arg 1: 45 arg 2: 67.8 >>> tupleVarArgs('abc',123,'xyz',456.7) arg 1: abc arg 2: 123 another arg: xyz another arg: 456.7
2)、**关键字变量参数(字典)
>>> def dictVarArgs(arg1, arg2 = "defaultB", **theRest): print 'arg 1:', arg1 print 'arg 2:', arg2 for eachXtrArg in theRest.keys(): print 'Xtra arg %s: %s' %(eachXtrArg, str(theRest[eachXtrArg])) >>> dictVarArgs(1220, 740.0, c = 'gmail') arg 1: 1220 arg 2: 740.0 Xtra arg c: gmail
>>> dictVarArgs(arg2 = 'tales', c = 123, d = 'zoo', arg1 = 'my') arg 1: my arg 2: tales Xtra arg c: 123 Xtra arg d: zoo
>>> dictVarArgs('one', d = 10, e = 'zoo', girls = ('Jenny', 'Penny')) arg 1: one arg 2: defaultB Xtra arg girls: ('Jenny', 'Penny') Xtra arg e: zoo Xtra arg d: 10
3)、组合使用
>>> def newfoo(arg1, arg2, *t, **d): print 'arg1 is :', arg1 print 'arg2 is :', arg2 for eacht in t: print 'add non-keyword:', eacht for eachd in d.keys(): print "add keyword '%s': %s" %(eachd, d[eachd]) >>>newfoo(10, 20, 30, 40, foo = 50, bar = 60) arg1 is : 10 arg2 is : 20 add non-keyword: 30 add non-keyword: 40 add keyword 'foo': 50 add keyword 'bar': 60 >>> newfoo(2,4,*(6,8),**{'jzhou':22,'James':45}) arg1 is : 2 arg2 is : 4 add non-keyword: 6 add non-keyword: 8 add keyword 'jzhou': 22 add keyword 'James': 45 >>> atuple=(7,8,9) >>> adict={'jzhou':22} >>> newfoo(1,2,3,x=4,y=5,z=6,*atuple ,**adict) arg1 is : 1 arg2 is : 2 add non-keyword: 3 add non-keyword: 7 add non-keyword: 8 add non-keyword: 9 add keyword 'y': 5 add keyword 'jzhou': 22 add keyword 'z': 6 add keyword 'x': 4
变量
(1)、变量作用域
python能够改变变量作用域的代码段是def、class、lamda
>>> def scopetest(): localvar=6; print(localvar) >>> scopetest() 6 >>> scopetest(localvar) #在函数外不能访问lcoalvar Traceback (most recent call last): File "<pyshell#74>", line 1, in <module> scopetest(localvar) NameError: name 'localvar' is not defined
if/elif/else、try/except/finally、for/while 并不能涉及变量作用域的更改,也就是说他们的代码块中的变量,在外部也是可以访问的
>>> if True: a=3 print a else: print 'not equals 3' 3 >>> a #外部也可以访问 3
(2)、局部变量和全局变量
#局部变量 >>> def func(x): print 'x is', x x = 2 print 'Changed local x to', x >>> x=50 >>> func(x) x is 50 Changed local x to 2 >>> x 50 #全局变量 >>> def func(): global x #定义全局变量x print 'x is', x x = 2 print 'Changed local x to', x >>> x=50 >>> func() x is 50 Changed local x to 2 >>> x 2
lambda匿名函数
使用方法:lambda [arg1[,arg2,arg3,...,argn]] : expression
>>> Factorial = lambda x: x > 1 and x * Factorial(x - 1) or 1 # x>1时求x的阶乘,其它返回1 >>> print Factorial(6) # 6! 720 >>> max = lambda a, b: (a > b) and a or b # a>b时返回a,否则返回b >>> print max(2,4) 4 >>> x,y=11,12 >>> print (lambda:x+y)() #使用默认的x,y 23 >>> print (lambda x:x+y)(x) #传的参数是x,y使用默认的12 23 >>> print (lambda x:x+y)(y) #传的参数是y,则y替换x 24
Generator生成器
可以保存状态的函数,用yield指令(不是return)返回一个值,并保存当前整个函数执行状态,等待下一次调用,如此循环往复,直至函数末尾,发生StopIteration异常。generator利用next()来获取下一个返回值。
>>> def gen(n): for i in xrange(n): yield i >>> g=gen(5) >>> g.next() 0 >>> g.next() 1 >>> for x in g: print x 2 3 4 >>> print g.next() Traceback (most recent call last): File "<pyshell#128>", line 1, in <module> print g.next() StopIteration #迭代已停止
Iterations迭代器
iter and next函数
>>> L=[1,2,3] >>> I=iter(L) >>> print I.next() 1 >>> print I.next() 2 >>> print I.next() 3 >>> print I.next() Traceback (most recent call last): File "<pyshell#134>", line 1, in <module> print I.next() StopIteration #迭代停止 >>> for x in I: print (x) #已经迭代完了 >>> Y=iter(L) >>> while True: try: X=next(Y) except StopIteration: break print X**2 1 4 9
>>> R=range(3) # R=[0,1,2] 列表 >>> I1,I2=iter(R),iter(R) >>> print next(I1),next(I1),next(I2) 0 1 0
内建函数
(1)、enumerate函数 ——获得数组,或列表的索引及值
>>> string = 'hello' >>> print list(enumerate(string)) [(0, 'h'), (1, 'e'), (2, 'l'), (3, 'l'), (4, 'o')] >>> for index,value in enumerate(string): print index, value 0 h 1 e 2 l 3 l 4 o
(2)、filter函数
filter(bool_func,seq):此函数的功能相当于过滤器。调用一个布尔函数bool_func来迭代遍历每个seq中的元素;返回一个使bool_seq返回值为true的元素的序列。
>>> def f(x): return x % 2 != 0 and x % 3 != 0 >>> print filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23]
(3)、map函数
map(func,seq1[,seq2...]):将函数func作用于给定序列的每个元素,并用一个列表来提供返回值;如果func为None,func表现为身份函数,返回一个含有每个序列中元素集合的n个元组的列表。
>>> def cube(x): return x*x*x >>> print map(cube,range(1,5)) [1, 8, 27, 64] >>> print filter (cube,range(1,5)) [1, 2, 3, 4] >>> print map(lambda x:x*2,[1,2,3,4,[5,6,7]]) [2, 4, 6, 8, [5, 6, 7, 5, 6, 7]]
None参数:
>>> map(None,'abc','xyz123') [('a', 'x'), ('b', 'y'), ('c', 'z'), (None, '1'), (None, '2'), (None, '3')]
(4)、reduce函数
reduce(func,seq[,init]):func 为二元函数,将func作用于seq序列的元素,每次携带一对(先前的结果以及下一个序列的元素),连续的将现有的结果和下一个值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值:如果初始值init给定,第一个比较会是init和第一个序列元素而不是序列的头两个元素。
>>> print reduce((lambda x, y: x + y), [1, 2, 3, 4]) 10 >>> print reduce((lambda x, y: x * y), [1, 2, 3, 4]) 24
(5)、zip函数
zip允许用户使用for循环访问平行的多个序列,zip将一个或多个序列作为参数,然后返回一系列的与序列中项平行的元组。
>>> x, y = [1, 2, 3], [4, 5, 6] >>> print zip(x, y) [(1, 4), (2, 5), (3, 6)] >>> print list(zip(x, y)) [(1, 4), (2, 5), (3, 6)] >>> print dict(zip(x, y)) {1: 4, 2: 5, 3: 6} >>> print tuple(zip(x, y)) ((1, 4), (2, 5), (3, 6)) >>> T1, T2, T3 = (1,2,3), (4,5,6), (7,8,9) >>> print list(zip(T1, T2, T3)) [(1, 4, 7), (2, 5, 8), (3, 6, 9)] >>> print tuple(zip(T1, T2, T3)) ((1, 4, 7), (2, 5, 8), (3, 6, 9))
(6)、type函数——得到对象的类型
>>> type(12) <type 'int'> >>> type('hello') <type 'str'> >>> type(type(42)) <type 'type'> >>> type([].append) <type 'builtin_function_or_method'>
(7)、cmp函数——比较两个对象是否相等
>>> cmp(1,2) -1 >>> cmp(3,3) 0 >>> cmp(0xFF,255) 0
(8)、类型转换
#类型转换 >>> float(4) 4.0 >>> complex (2.4,8) #转换为复数 (2.4+8j) >>> coerce(1j,123) #复数表示 (1j, (123+0j)) #ASCII转换 >>> ord('s') 115 >>> chr(115) 's' #进制转换 >>> hex(255) #16进制 '0xff' >>> oct(255) #8进制 '0377'