Python学习Day14

一、迭代器
    1.什么是迭代器
        什么是迭代?
            迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续
            下列循环只是单纯的重复
            while True:
                print(l)
                
            基于索引的迭代取值
            l=['a','b','c']
            i=0
            
            while i < len(l):
                print(l[i])
                i+=1
        什么是迭代器?
            迭代取值的工具
            
    2.为什么要用迭代器
        迭代器
            优点
                1.提供一种不依赖索引的迭代取值方式
                2.更节省内存
            缺点:
                1.不如按照索引的取值方式灵活
                2.取值一次性的,只能往后取,无法预测值的个数
                
    3.如何用迭代器
        可迭代的对象:str\list\tuple\dict\set\文件对象
            但凡内置有__iter__方法的对象都称之为可迭代对象
            
        迭代器对象:文件对象
            既内置有__iter__方法又内置有__next__方法的对象都称之为迭代器对象
            
            
        调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象
        
        
    s='abcdef'
    l=['a','b','c']
    d={'k1':111,'k2':222,'k3':333}

    iter_d=d.__iter__()
    # print(iter_d)

    try:
        print(iter_d.__next__())
        print(iter_d.__next__())
        print(iter_d.__next__())
        print(iter_d.__next__())
    except StopIteration:
        print('取值完毕')    
            
            

    d={'k1':111,'k2':222,'k3':333}
    d={1,2,3,4,5}
    d=[1,2,3,4]

    iter_d=d.__iter__()
    iter_d=iter(d) #d.__iter__

    print(next(iter_d)) #iter_d.__next__()

    print(len(d))
    print(d.__len__())


    print(iter_d.__iter__().__iter__().__iter__() is iter_d)

    print(d.__iter__().__next__())
    print(d.__iter__().__next__())
    print(d.__iter__().__next__())



    while True:
        try:
            v=iter_d.__next__()
            print(v)
        except StopIteration:
            break

    print('第二次取值')

    iter_d=d.__iter__()
    while True:
        try:
            v=iter_d.__next__()
            print(v)
        except StopIteration:
            break


    for k in d:
        print(k)

    for循环的底层原理:
    1. 调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj
    2. 调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration
    3. 捕捉异常结束循环            
            
二、生成器
    生成器就是一种自定义的迭代器
    如何得到生成器?
        但凡函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器
        
        
    def func():
        print('first')
        yield 1
        print('second')
        yield 2
        print('third')
        yield 3
        
        
    g = func()
    print(g)
    
    res1 = next(g)
    print(res1)
    
    res2 = next(g)
    print(res2)
    
    res3 = next(g)
    print(res3)
    
    next(g)
    
    总结yield:
    1.提供一种自定义迭代器的解决方案
    2.yield & return
        相同点:都可以返回值,返回值没有类型限制\个数限制
        不同点:return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值
    
    
    def my_range(start,stop,step=1):
        while start<stop:#5<5
            yield start # 3
            start+=step # start=5
            
    range(1,5,2) # 1 3
    for i in my_range(1,500000000000000000000,2):# 1 3
        print(i)
        
三、函数的递归调用与二分法
    1.函数的递归调用:
        在调用一个函数的过程又直接或间接地调用该函数本身,称之为递归调用
        
        递归必须满足两个条件:
            1.每进入下一次递归调用,问题的规模都应该有所减少
            2.递归必须有一个明确的结束条件
    以下递归只是单纯的重复,没有意义
    def func():
        print(1)
        print(2)
        print(3)
        func()
        
    func()
    
    def bar():
        print('from bar')
        foo()
        
    def foo():
        print('from foo')
        bar()
        
    foo()
        递归有两个明确的阶段:
            1.回溯
            2.递推
            
    
    age(5)=age(4)+2
    age(4)=age(3)+2
    age(3)=age(2)+2
    age(2)=age(1)+2
    age(1)=18

    age(n)=age(n-1)+2  # n > 1
    age(1)=18          # n = 1

    def age(n):
        if n == 1:
            return 18
        return age(n-1)+2

    print(age(5))


    l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

    def func(list1):
        for item in list1:
            if type(item) is not list:
                print(item)
            else:
                # 如果是列表,应该...
                func(item)

    func(l)


    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]

    find_num=203
    for num in nums:
        if num == find_num:
            print('find it')
            break
    else:
        print('not exists')            

            
    2.二分法
    
    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]
    def binary_search(list1,find_num):
        print(list1)
        if len(list1) == 0:
            print('not exist')
            return
        mid_index=len(list1) // 2
        if find_num > list1[mid_index]:
            # in the right
            binary_search(list1[mid_index + 1:],find_num)
        elif find_num < list1[mid_index]:
            # in the left
            binary_search(list1[:mid_index],find_num)
        else:
            print('find it')

    binary_search(nums,203)    
            
            
            
            
        
            

 

posted on 2018-12-04 19:24  鲨鱼辣椒L  阅读(109)  评论(0编辑  收藏  举报

导航