您的位置:首页 > 编程语言 > Python开发

python学习笔记之装饰器、递归、算法(第四天)

2016-01-31 23:47 453 查看
参考老师的博客:

金角:http://www.cnblogs.com/alex3714/articles/5161349.html

银角:http://www.cnblogs.com/wupeiqi/articles/4963027.html

一、冒泡算法实例:

a = [32,5,22,41,7,31,12,102,74,37,9,25]

1、方法1:

count = 0
for i in range(len(a)):
for j in range(len(a)-1):
if a[j] > a [j+1]:
tmp = a[j]
a[j] = a[j+1]
a[j+1] = tmp
count += 1
count += 1
print('count is %d' % count)
print(a)

注:此方法会循环12*11次,会进行多次不必要的判断


2、方法2:(此方法是将大的数字逐步往后移)


count = 0
for i in range(1,len(a)):
for j in range(len(a)-i):
if a[j] > a [j+1]:
tmp = a[j]
a[j] = a[j+1]
a[j+1] = tmp

count += 1
count += 1
print(a)



3、方法3:(注:此方法是将找到小的数字往前移)


for i in range(len(a)-1):
for j in range(i+1,len(a)):
if a[i] > a[j]:                 #小于号表示遍历一遍找到最大值放到第一位,依次查找;如果是大于号则相反
tmp = a[i]
a[i] = a[j]
a[j] = tmp
print(a)


二、递归

特点

递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

要求

递归算法所体现的“重复”一般有三个要求:
一是每次调用在规模上都有所缩小(通常是减半);
二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。

实例:
对一个数字进行除2求值,直到小于等于1时退出并输出结果:

1、简单顺时针输出:
a = [i for i in range(4) for j in range(4)]
b = [[i for i in range(4)] for j in range(4)]
print(a)
print(b)

for i in range(len(b)):
c = [bb[i] for bb in b]
print(c)

2、对称互换输出:
for r_index,row in enumerate(b):
for c_index in range(len(row)):
temp = b[c_index][r_index]
b[c_index][r_index] = b[r_index][c_index]
b[r_index][c_index] = temp
print(row)

结果:
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]


2组数据旋转

三、装饰器

参考银角大王的装饰器:http://www.cnblogs.com/wupeiqi/articles/4980620.html

装饰器的语法以@开头,接着是装饰器要装饰的函数的申明等。
其实总体说起来,装饰器其实也就是一个函数,一个用来包装函数的函数,装饰器在函数申明完成的时候被调用,调用之后申明的函数被换成一个被装饰器装饰过后的函数。

当原函数有形参时,在装饰的函数中也需要有相应的形参func(args);

当原函数有return返回值时,在装饰的函数中也必须有returne func(args);

装饰器分为无参装饰和有参装饰:

★无参装饰
定义方法如下:
比如先定义一个装饰方法:

def deco(func):
"""无参数调用decorator声明时必须有一个参数,这个参数将接收要装饰的方法"""
print('第一个装饰器') #进行额外操作
return func #返回一个可调用对象(此例还是返回作为输入参数的方法),返回一个新函数时,新函数可以是一个全局方法或者decorator函数的内嵌函数,只要函数的签名和被装饰的函数相同

@deco
def MyFunc(args): #应用@deco修饰的方法
print('my first decorator',args)

return('nihao',args)

MyFunc('wangkai') #调用被装饰的函数
MyFunc('kevin')

info = MyFunc('gonghui')
print(info)

注意:当使用上述方法定义一个decorator方法时,函数体内的额外操作只在被装饰的函数首次调用时执行;

如果要保证额外操作在每次调用被装饰的函数时都执行,需要换成如下的写法:
def deco(func):
def replaceFunc(args): #定义一个内嵌函数,此函数包装了被装饰的函数,并提供额外操作的代码
print('第一个装饰器') #进行额外操作
return func(args) #产生对被装饰函数的调用
return replaceFunc #由于返回的是这个新的内嵌函数,所以确保额外操作每次调用得以运行

@deco
def MyFunc(args): #应用@deco修饰的方法
print('my first decorator',args)
return('nihao',args)

MyFunc('wangkai') #调用被装饰的函数
MyFunc('kevin')
info = MyFunc('gonghui')
print(info)

[b]★有参装饰:[/b]

def decoWithArgs(arg):
"""由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,
所以必须返回一个decorator函数, 由它对被装饰的函数进行封装处理"""
def newDeco(func): #定义一个新的decorator函数
def replaceFunc(args): #在decorator函数里面再定义一个内嵌函数,由它封装具体的操作
print('第一个装饰器') #进行额外操作
aa = func(args) #对被装饰函数进行调用

print('再见')

return aa
return replaceFunc
return newDeco #返回一个新的decorator函数

@decoWithArgs("demo")
def MyFunc(args): #应用@decoWithArgs修饰的方法
print('my first decorator',args)
return('nihao',args)

MyFunc('wangkai') #调用被装饰的函数
MyFunc('kevin')
info = MyFunc('gonghui')
print(info)

当我们对某个方法应用了装饰方法后, 其实就改变了被装饰函数名称所引用的函数代码块入口点,使其重新指向了由装饰方法所返回的函数入口点。由此我们可以用decorator改变某个原有函数的功能,添加各种操作,或者完全改变原有实现。

[b][b]★[/b]多参数函数的装饰器:[/b]

def Before(request,kargs):
print 'before:%s==%s' % (request,kargs)
return(kargs)

def After(request,kargs):
print 'after:%s==%s' % (request,kargs)
return(kargs)

def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs):
before_result = before_func(request,kargs)
main_result = main_func(request,kargs)
after_result = after_func(request,kargs)
return wrapper
return outer

@Filter(Before, After)
def Index(request,kargs):
print 'index:%s==%s' % (request,kargs)
return(kargs)

Index('nihao','aaa')



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: