第十二次课:Python函数(三)
列表生成式列表生成式是Python函数的高级特性,顾名思义就是用来创建列表(list)的生成式。
基础语法:
如 就是一个列表生成式。首先迭代iterable 里所有内容, 每一次迭代, 都把iterable 里相应内容放到iter_var 中, 再在表达式exp 中应用该 iter_var 的内容, 最后用表达式的计算值生成一个新的列表。
print '利用range()生成一个list' print range(1,11)
print '计算1-10各自的平方'
for i in xrange(1,11):
print i*i,
print '\n函数形式实现1-10各自的平方'
def fuc():
L1=[]
for i in xrange(1,11):
L1.append(i*i)
return L1
print fuc()
print '\n利用列表生成式计算1-10各自的平方'
运行结果:
利用range()生成一个list
计算1-10各自的平方
1 4 9 16 25 36 49 64 81 100
函数形式实现1-10各自的平方
利用列表生成式计算1-10各自的平方
从例子中可以很直观的看出无论是用循坏还是普通函数,代码都有好几行,而使用列表生成式就一行代码实现了功能,及简化了代码又有更好的复用性。
生成式for循环后还是使用if判断语句,如下例子:
print '1-100间的所有偶数' L1=
print L1
print '1-100间的所有奇数'
L2=
print L2
print '1-100间所有偶数的平方'
L3=
print L3
print '1-100间所有奇数的平方'
L4=
print L4
运行结果:
1-100间的所有偶数
1-100间的所有奇数
1-100间所有偶数的平方
1-100间所有奇数的平方
生成式可以使用两层循环,如下例子:格式化输出某位学生所有科目的考试成绩
dic={'chinese':98,'math':99,'pysical':89,'chemistry':80,'biology':96} print dic.items()
L1=
print L1
运行结果:
[('pysical', 89), ('biology', 96), ('chemistry', 80), ('math', 99), ('chinese', 98)] ['pysical:89', 'biology:96', 'chemistry:80', 'math:99', 'chinese:98']
列表生成式虽然简洁易用,但有的情形不用:当需要只是执行一个循环的时候;当有内建的操作或者类型能够以更直接的方式实现的;如果需要对每个元素都调用并且返回结果时。
生成器
当我们调用一个普通的python函数时,一般都是从函数的第一行开始执行,直到遇到return语句或者异常或者函数的最后一行。这样,函数就将控制权交还与调用者,函数中的所有工具以及局部变量等数据都将丢失。再次调用这个函数的时候,所有的局部变量,堆栈信息都将重新创建,跟之前的调用再无关系。
生成器(generator)其实对我们来说并不陌生,最简单的方法就是把列表的方括号改成圆括号,如下:
L1= L2=(y for y in xrange(1,5))
print type(L1),L1
print type(L2),L2
print L2.next()
print L2.next()
print L2.next()
print L2.next()
print L2.next()
运行结果:
<type 'list'> <type 'generator'> <generator object <genexpr> at 0x0000000004F2D480>
1
2
3
4
Traceback (most recent call last):
<type 'generator'> <generator object <genexpr> at 0x00000000055BD480>
File "C:/Users/YangQing/PycharmProjects/Test/Iterator.py", line 44, in <module>
L2.next()
StopIteration
有时候我们并不希望函数只返回一个值,而是希望返回一个序列。要做到这一点,这种函数需要能够保存自己的工作状态。这样的话,就不能使用我们通常所使用的return语句,因为一旦使用return语句,代码执行的控制权就交给了函数被调用的地方,函数的所有状态将被清零。在这种情况下,我们就需要使用yield关键字。含有yield关键字的地方,就是一个生成器(generator)。
print '普通函数' def sn(n):
ss=[]
for i in xrange(n):
ss.append(i*i)
return ss
for b in sn(5):
print b,
print '\n生成器'
def sm(m):
for i in xrange(m):
yield i*i
for a in sm(5):
print a,
运行结果:
普通函数
0 1 4 9 16
生成器
0 1 4 9 16
在python中,生成器通过生成器函数生成,生成器函数定义的方法跟普通函数定义的方法一致。唯一不同的地方是,生成器函数不用return返回,而是用yield关键字一次返回一个结果,在每个结果之间挂起与继续他们的状态,来自动实现迭代(循环)。
(1)当调用生成器函数时候,函数返回的,只是一个生成器对象,并没有真正执行里面的逻辑;
(2)当next()方法第一次被调用以后,生成器才真正开始工作。一旦遇到yield语句,代码便停止运行。注意此时的停止运行跟return的是不一样的;
(3)调用next()方法的时候,返回的是yield处的参数值;
(4)当继续调用next()方法时,代码将在上一次停止的yield语句处继续执行,并且到下一个yield处停止;
(5)一直到后面没有yield语句,最后抛出StopIteration的异常;
迭代器
在Python中,如果给定一个列表(list)或元组(tuple),我们可以通过for循环来遍历这个列表(list)或元组(tuple),这种遍历我们成为迭代(Iteration)。在Python中,迭代是通过 for ... in 来完成的。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问。
迭代操作就是对于一个集合,无论该集合是有序还是无序,我们用 for 循环总是可以依次取出集合的每一个元素。这类集合称作可迭代对象,字典就是典型的可迭代对象,下面举例:
dic={'Name':'John','Hob':'Music','Code':'0590','Address':'Fuzhou'} print dir(dic)
print dic.items()
for a in dic.iteritems():
print a
for b in dic.iterkeys():
print b
for c in dic.itervalues():
print c
运行结果:
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues'] [('Code', '0590'), ('Hob', 'Music'), ('Name', 'John'), ('Address', 'Fuzhou')]
('Code', '0590')
('Hob', 'Music')
('Name', 'John')
('Address', 'Fuzhou')
Code
Hob
Name
Address
0590
Music
John
Fuzhou
装饰器
装饰器(Decorator)其实就是一个以函数作为参数并返回一个替换函数的可执行函数。
>>> def outer(func1): ... def inner():
... print "before func1"
... ret = func1() # 1
... return ret + 1
... return inner
>>> def foo():
... return 1
>>> decorated = outer(foo) # 2
>>> decorated()
before func1
首先,定义了一个带单个参数func1的名为outer的函数。然后在outer内部定义了一个内嵌函数inner。inner函数将打印一行字符串然后调用func1,并在#1处获取其返回值。在每次outer被调用时,func1的值可能都会不同,但不论func1是什么函数,都将调用它。最后,inner返回func1()的返回值加1。在#2 处可以看到,当调用赋值给decorated的返回函数时,得到的是一行文本输出和返回值2,而非期望的调用foo的返回值1。
练习:利用函数实现九九乘法表:
print '常规方法一:for循环' for i in xrange(1,10):
for j in xrange(1,i+1):
print j,"x",i,"=",j*i,"",
# print '{} x {} = {}\t'.format(i, j, i * j),
# print '%d x %d = %d\t'%(i,j,i*j),
if j>=i:
print('')
print '常规方法二:while循坏'
i=0
j=0
while i<9:
i+=1
while j<9:
j+=1
# print j,"x",i,"=",j*i,"",
print '{} x {} = {}\t'.format(i, j, i * j),
# print '%d x %d = %d\t'%(i,j,i*j),
if i==j:
j=0
print('')
break
print '函数方法'
def nn():
for i in xrange(1, 10):
for j in xrange(1, i + 1):
# print j,"x",i,"=",j*i,"",
# print '{} x {} = {}\t'.format(i, j, i * j),
print '%d x %d = %d\t'%(i,j,i*j),
if j >= i:
print('')
return
nn()
运行结果:
常规方法一:for循环
1 x 1 = 1
1 x 2 = 22 x 2 = 4
1 x 3 = 32 x 3 = 63 x 3 = 9
1 x 4 = 42 x 4 = 83 x 4 = 124 x 4 = 16
1 x 5 = 52 x 5 = 103 x 5 = 154 x 5 = 205 x 5 = 25
1 x 6 = 62 x 6 = 123 x 6 = 184 x 6 = 245 x 6 = 306 x 6 = 36
1 x 7 = 72 x 7 = 143 x 7 = 214 x 7 = 285 x 7 = 356 x 7 = 427 x 7 = 49
1 x 8 = 82 x 8 = 163 x 8 = 244 x 8 = 325 x 8 = 406 x 8 = 487 x 8 = 568 x 8 = 64
1 x 9 = 92 x 9 = 183 x 9 = 274 x 9 = 365 x 9 = 456 x 9 = 547 x 9 = 638 x 9 = 729 x 9 = 81
常规方法二:while循坏
1 x 1 = 1
1 x 2 = 22 x 2 = 4
1 x 3 = 32 x 3 = 63 x 3 = 9
1 x 4 = 42 x 4 = 83 x 4 = 124 x 4 = 16
1 x 5 = 52 x 5 = 103 x 5 = 154 x 5 = 205 x 5 = 25
1 x 6 = 62 x 6 = 123 x 6 = 184 x 6 = 245 x 6 = 306 x 6 = 36
1 x 7 = 72 x 7 = 143 x 7 = 214 x 7 = 285 x 7 = 356 x 7 = 427 x 7 = 49
1 x 8 = 82 x 8 = 163 x 8 = 244 x 8 = 325 x 8 = 406 x 8 = 487 x 8 = 568 x 8 = 64
1 x 9 = 92 x 9 = 183 x 9 = 274 x 9 = 365 x 9 = 456 x 9 = 547 x 9 = 638 x 9 = 729 x 9 = 81
函数方法
1 x 1 = 1
1 x 2 = 22 x 2 = 4
1 x 3 = 32 x 3 = 63 x 3 = 9
1 x 4 = 42 x 4 = 83 x 4 = 124 x 4 = 16
1 x 5 = 52 x 5 = 103 x 5 = 154 x 5 = 205 x 5 = 25
1 x 6 = 62 x 6 = 123 x 6 = 184 x 6 = 245 x 6 = 306 x 6 = 36
1 x 7 = 72 x 7 = 143 x 7 = 214 x 7 = 285 x 7 = 356 x 7 = 427 x 7 = 49
1 x 8 = 82 x 8 = 163 x 8 = 244 x 8 = 325 x 8 = 406 x 8 = 487 x 8 = 568 x 8 = 64
1 x 9 = 92 x 9 = 183 x 9 = 274 x 9 = 365 x 9 = 456 x 9 = 547 x 9 = 638 x 9 = 729 x 9 = 81
页:
[1]