pythonL4

迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
names=iter([‘lucy‘,‘lily‘,‘mike‘])
print(names)
print(names.__next__())#lucy
print(names.__next__())#lily
print(names.__next__())@mike
print(names.__next__())#StopIteration

生成器generator

定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器

def cash_money(amount):
    while amount>0:
        amount-=100
        yield 100#yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
        print("又来取钱啦!")
atm=cash_money(500)
print(type(atm))#<class ‘generator‘>
print(atm.__next__())#100
print(atm.__next__())#又来取钱啦!100
print(atm.__next__())#又来取钱啦!100
print(atm.__next__())#又来取钱啦!100
print(atm.__next__())#又来取钱啦!100

还可通过yield实现在单线程的情况下实现并发运算的效果:异步

import time
def consumer(name):
    while True:
        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(10):
        time.sleep(1)
        print("做了2个包子!")
        c.send(i)
        c2.send(i)
producer("alex")

装饰器

def login(func):#func=tv
    def inner(arg):#arg=‘lily‘
        print("passed user verification...")
        return func(arg)#执行func(arg)=tv(‘lily‘)
    return inner#返回的inner,inner代表的是函数,非执行函数,其实就是将原来的tv(name)函数塞进另外一个函数中
def home(name):
    print("Welcome [%s] to home page"%name)
@login#装饰器
def tv(name):#执行tv(‘lily‘)
    print("Welcome [%s] to tv page"%name)
def moive(name):
    print("Welcome [%s] to moive page"%name)
tv(‘lily‘)#tv的内存地址加()

上述代码的理解解析:

  • 执行login函数,并将 @login下面的函数tv作为login函数的参数,即:@login 等价于login(tv)

所以,内部就会去执行:
    def inner:
        print("passed user verification...")
        return func()   # func是参数,此时 func 等于 tv
    return inner     # 返回的 inner,inner代表的是函数,非执行函数
其实就是将原来的 tv 函数塞进另外一个函数inner中

  • 将执行完的 login 函数返回值赋值给@login下面的函数的函数名tv

login函数的返回值是inner:
   def inner:
        print("passed user verification...")
        return func()#tv(),此处的 tv表示原来的tv函数
然后,将此返回值再重新赋值给tv,即:
新tv = def inner:
            print("passed user verification...")
            return 原来tv() 
所以,以后业务部门想要执行tv函数时,就会执行 新tv函数,在 新tv函数内部先执行验证,再执行原来的tv函数,然后将原来tv函数的返回值返回给了业务调用者。如此一来, 即执行了验证的功能,又执行了原来tv函数的内容,并将原tv函数返回值返回给业务调用

递归

递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法解决问题的特点:

(1) 递归就是在过程或函数里调用自身。

(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。

(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

递归算法所体现的“重复”一般有三个要求:

一是每次调用在规模上都有所缩小(通常是减半);

二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);

三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。

def calc(n):
    print(n)#10 5 2.5 1.25
    if n/2>1:
        res=calc(n/2)#calc(10/2) calc(5/2) calc(2.5/2)
        print(‘res:‘,res)#1.25 2.5 5等同于执行calc()print(n)print("N:",n)#1.25 2.5 5 10 return n #N:1.25->return n->calc(1.25)->res:1.25->n=1.25*2->N:2.5->return n->calc(2.5)->res:2.5->n=2.5*2->N:5->return n->calc(5)->res:5->n=5*2->N:10->return 10calc(10)

10
5.0
2.5
1.25

#1.25/2>1不成立,执行print("N:",n)
N: 1.25
res: 1.25
N: 2.5
res: 2.5
N: 5.0
res: 5.0
N: 10

通过递归实现斐波那契数列:def func(arg1,arg2,stop):
    if arg1==0:
        print(arg1,arg2)
    arg3=arg1+arg2
    print(arg3)
    if arg3<stop:
        func(arg2,arg3,stop)
func(0,1,20)

算法基础之二分查找

def binary_search(data_source,find_n):[1,4,7,10,13,16,19]
    mid=int(len(data_source)/2)#data_source中间元素对应的索引值3,data_source[mid]=data_source[3]=10
    if len(data_source)>1:
        if data_source[mid]>find_n:
            print("data in left of [%s]"%data_source[mid])
            binary_search(data_source[:mid],find_n)#data_source[:mid]:切分,把右边的切去,保留左边的
        elif data_source[mid]<find_n:
            print("data in right of [%s]"%data_source[mid])
            binary_search(data_source[mid:],find_n)#data_source[mid:]:切分,把左边的切去,保留右边的        else: print("found find_n",data_source[mid]) else: print("can‘t find it") data=list(range(1,20,3)) #print(data) binary_search(data,13)
时间: 2024-12-15 23:10:45

pythonL4的相关文章