zoukankan      html  css  js  c++  java
  • 迭代器与生成器

    1.迭代器

    1.1什么是迭代?

        迭代是一个重复的过程,但是每次重复都是基于上一次重复的结果而继续

    1.2什么是迭代器?

        迭代器是迭代取值的工具

    1.3为什么要用迭代器?(迭代器的优缺点)

    优点:1.提供一种不依赖索引取值的方式,使一些没有索引的对象也可以被迭代取值

               2.更节省内存,每一次只取一个值。

    缺点:1.不如索引取值那样灵活,可能无法立刻就取到需要的值

               2.取值一次性,只能往后取,无法预测值的个数

    1.4如何用迭代器?

    可迭代对象:内置有__iter__方法的对象都称之为可迭代对象

    包括: str list tuple dict set 文件对象

    迭代器对象:  内置既有__iter__方法又有__next__方法的对象称为迭代器对象

    包括: 文件对象

    因此,迭代器对象一定是可迭代对象,但是可迭代对象不一定是迭代器对象!!!

    可迭代对象通过调用其内置的__iter__方法,会有一个返回值,这个返回值就是一个对应该可迭代对象的迭代器!

    调用返回值中的next方法,可以进行取值!

    for循环的底层原理便是用到了迭代器的原理:

    1. 调用in后面那个值/对象的__iter__方法,拿到一个迭代器对象iter_obj

    2. 调用迭代器对象iter_obj.__next__()将得到的返回值赋值变量名k,循环往复直到取值完毕抛出异常StopIteration

    3.捕捉异常结束循环

    迭代器练习:

    #利用迭代器的原理,取出字典中的值
    d={'k1':111,'k2':222,'k3':333}  #d是一个可迭代对象
    iter_d=d.__iter__() #iter_d是一个迭代器
    while True:
        try:
            v=iter_d.__next__()
            print(v)
        except StopIteration:
            break
    
    ###当我迭代取完值后,我再去值的时候就会因为取不到值而报错,这个时候我们可以用try--###---except机制,捕捉异常,是代码不报错,正常走下去!
    View Code

    2.生成器

    2.1定义:生成器就是一种自定义的迭代器

    2.2如何得到生成器?

        但凡函数内出现yiled关键字,调用函数执行到yiled关键字处时暂停函数执行,会得到一个跟在yiled后面的返回值,该返回值就是生成器对象,即自定义的迭代器。

        注意:得到的是一个生产器对象哦,并不是一个普通的值

    def func():
        print('first')
        yield 1
        print('second')
        yield 2
        print('third')
        yield 3
    
    
    g=func()
    print(g)
    
    
    #输出为<generator object func at 0x0000021B70E557D8>
    
    #需要在代码后写上next(g)才能把值输出来

    2.3 yield关键字提供一种自定义迭代器的解决方案

         yield & return

          相同点:都可以返回值,返回值没有类型限制个数限制

          不同点:return 只能返回一次值,yield却可以让函数暂时在某一个位置停留,下一次再调用

                        next 的时候从上次暂停的位置继续往下执行,可以返回多次值

    小练习:利用生成器做一个自定义的随机数取值函数,限定范围和步长取值

    def my_range(start,end,step):
        while start <end:
            yield start
            start+=step
    
    res=my_range(1,5,3)
    while True:
        try:
            print(next(res))
        except StopIteration:
            break
    View Code

    3.递归函数

    定义:再调用一个函数的过程又直接或者间接地调用该函数本身,称之为递归调用

    递归必须满足两个条件:1.每进入下一次递归调用,问题的规模都应该有所减少

                                           2.递归必须有一个明确的结束条件

    递归有两个明确的阶段:1.回溯  2.递推

    回溯是指一个函数在其内部又调用了它这个函数(参数可以不同),减小其规模,进入到了一个循环的过程。

    递推指的是在回溯到一个阶段,最后的函数满足一定的条件时,最后一个函数结束执行,然后往前返回,函数结束执行的过程。

    小练习:利用递归函数,将列表中所有数字输出来

    def func(list1):
        for item in list1:
            if type(item) is not list:
                print(item)
            else:
                func(item)
    l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]
    func(l)
    View Code

    4.二分法

    取对象的中间值,与要寻找的值进行比较,然后进行切片,继续这个过程,直到找到这个值为止(或者直到对象中只有一个值还没有找到需要的值,那么对象中没有需要的值)

    def two_fen(num,list1):
        mid_index=len(list1)//2
        if len(list1)==0:
            print('列表中没有这个值')
            return
        if num>list1[mid_index]:
            return two_fen(num,list1[mid_index+1:])
        elif num<list1[mid_index]:
            return two_fen(num,list1[:mid_index])
        else:
            return num
    nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341]
    res=two_fen(24,nums)
    print(res)
    View Code

    了解知识点:

    在上述代码中,如果在使用递归函数时直接使用two_fen(num,list1[mid_index+1:]),这种方法而没有用retuen 时,

    这个递归函数最终是没有返回值的。这个知识点在博客Python 递归函数返回值为None的解决办法中有详解。

    杜绝秃头!!!
  • 相关阅读:
    分享Silverlight/WPF/Windows Phone一周学习导读(12月13日12月19日)
    分享Silverlight/WPF/Windows Phone一周学习导读(12月20日12月26日)
    关注Silverlight的未来 推荐注册微软Silverlight FireStarter大会
    Silverlight for Windows Phone Toolkit升级 新增四个控件
    分享Silverlight新鲜事(11月15日21日) PDC 10 Downloader
    分享Silverlight/WPF/Windows Phone一周学习导读(11月22日28日)
    微软副总裁Bob Muglia对Silverlight的公开道歉信
    分享Silverlight/WPF/Windows Phone一周学习导读(11月29日12月5日)
    [转]diff和patch
    Linux查看进程的所有子进程和线程
  • 原文地址:https://www.cnblogs.com/846617819qq/p/10058931.html
Copyright © 2011-2022 走看看