python-day4
当当当!写这篇随笔的时候,不出意外应该是新年过后了,再这里给大家拜个晚年咯~本期的python学习迎来了几个灰常灰常绕脑子的东西<迭代器><装饰器><递归><正则表达式>,老实说。这次的饰品看完后,感觉就是一个字:晕!两个字:很晕!
一.迭代器
迭代器和他的好基友生成器
迭代器是以iter()为使用条件的,并且只有next()一种使用的条件
names = iter(['k1','k2','k3']) print(names) print(names.__next__()) 输出结果:<list_iterator object at 0x000002065E9320B8> k1
可以看到迭代是使用iter()来定义的,如果是其他的定义方式,那么在例子中的print会直接把names变量里的元素全部打印出来,但使用了iter以后,可以看到打印的其实是一个内存的地址,而要输出结果则必须使用next()方法
names = iter(['k1','k2','k3']) print(names.__next__()) print(names.__next__()) 输出结果:k1 k2
可以看到,names中有3个元素,在迭代的情况下,元素的输出完全是由next方法来控制的,每一个next只能从变量中依次获取一个元素
names = iter(['k1','k2','k3']) print(names.__next__()) print(names.__next__()) print(names.__next__()) print(names.__next__()) 输出结果:k1 k2 k3 print(names.__next__()) StopIteration
可以看到,names中有3个元素,当next()的方法被调用四次以后,会直接报错,告诉你迭代已经被终止了
二.生成器
生成器其实是在函数中使用了yield方法的一种迭代器
def cash_out(amount):
while amount >0:
amount -= 100
#return 1
print('钱多多 %s' % amount)
yield 100
atm = cash_out(500)
print(type(atm))
print(atm.__next__())
print(atm.__next__())
print('OK~')
print(atm.__next__())
输出结果:
钱多多 400
100
钱多多 300
100
OK~
钱多多 200
100
这个例子是一个简单的生成器的例子,在函数中使用了yield方法,将整个函数变成了一个生成器,这样需要输出结果的时候只需要使用next方法即可,当整个函数运行到yield时,会暂停下来,等待被后续的next()方法继续调用,此时是可以执行其他的操作的,这样让整个循环的方式更加灵活
import time
def consumer(name):
print("%s 准备吃包子" % name)
while True:
baozi = yield
print('包子 %s 来了,被 %s 吃了'% (baozi,name))
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print('老子开始做包子啦')
for i in range(3):
time.sleep(1)
print('%s 做了2个包子!' % name)
c.send(i+1)
c2.send(i+1)
producer('Zero')
输出结果:
A 准备吃包子
B 准备吃包子
老子开始做包子啦
Zero 做了2个包子!
包子 1 来了,被 A 吃了
包子 1 来了,被 B 吃了
Zero 做了2个包子!
包子 2 来了,被 A 吃了
包子 2 来了,被 B 吃了
Zero 做了2个包子!
包子 3 来了,被 A 吃了
包子 3 来了,被 B 吃了
这个吃包子的例子就是一个使用生成器做的异步处理的方法,这里出现了一个baozi = yield 的方法,yield 不但可以输出值,更可以接受值,而send方法则可以将需要的值输送给yield
三.装饰器
装饰器,可以不严谨地把python的装饰器看做是一个包装函数的函数
def login(func):
def inner(*args):
print('welcome')
return func(*args)
return inner
@login
def tv(name,password):
print("Welcome [%s] to tv page,input your [%s]" % (name,password) )
return 5576
print(tv('zero','123456678'))
输出结果:
welcome
Welcome [zero] to tv page,input your [123456678]
5576
可以看到装饰器的使用例子,装饰器是包装在函数外的一个函数
四.递归
递归的解决方法是比较常见的解决一大类问题的处理方法,但是递归的处理效率较低
def calc(n):
print(n)
if n/2 > 1:
res = calc(n/2)
return n
calc(50)
输出结果:
50
25.0
12.5
6.25
3.125
1.5625
递归的方法就是在函数中调用函数本身,这里需要注意的是,递归必须要有一个出口,也就是递归终止的条件,否则会报错,python限制了无限次的递归为了保护计算机
def func(arg1,arg2,stop):
if arg1 == 0:
print('%s\n%s' %(arg1,arg2))
arg3 = arg1 + arg2
print(arg3)
if arg3 < stop:
func(arg2,arg3,stop)
func(0,1,30)
输出结果:
0
1
1
2
3
5
8
13
21
34
这个例子是就是递归的一个应用方法,菲波那切数列的计算,通过前后两个数字的相加,去寻找输入的数字是否在数列中的一个方法
五.算法
二分算法
def bs(arg1,arg2):
mid = int(len(arg1)/2)
if len(arg1) >= 1:
if arg1[mid] > arg2:
print('data in left of [%s]'% arg1[mid])
bs(arg1[:mid],arg2)
elif arg1[mid] < arg2:
print('data in right of [%s]'% arg1[mid])
bs(arg1[mid:],arg2)
else:
print('data is foud!![%s]'% arg1[mid])
else:
print('NON NO ')
if __name__ == "__main__":
data = list(range(1,600))
i = int(input('Please input your number:'))
bs(data,i)
输出结果:
Please input your number:3
data in left of [300]
data in left of [150]
data in left of [75]
data in left of [38]
data in left of [19]
data in left of [10]
data in left of [5]
data is foud!![3]
这个例子就是一个二分算法的例子,可以看到使用了递归的方法,将整个数列从中间进行截取,然后和输出的数字进行比较,大于中间数的,在右边,小于中间数的,在左边,然后再截取一半进行比较,以此类推下去,最后得出输出的数字是否在范围内
二维数组旋转
data = [[col for col in range(4)] for row in range(4)]
for row in data:
print(row)
print('------------')
for r_index,row in enumerate(data):
for c_index in range(r_index,len(row)):
tmp = data[c_index][r_index]
data[c_index][r_index] = row[c_index]
data[r_index][c_index] = tmp
print('------------')
for r in data:print(r)
输出结果:
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]
------------
------------
[0, 0, 0, 0]
[1, 1, 2, 3]
[2, 1, 2, 3]
[3, 1, 2, 3]
------------
[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 3]
[3, 3, 2, 3]
------------
[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
------------
[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
这个也是一种算法,没有用到递归,非常搞脑子的一个模型

浙公网安备 33010602011771号