• day14 迭代器和生成器


    1.迭代器

      名词解释

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

      #下列循环只是单纯的重复,没有意义

      while True:

        print(1)

      #基于索引的迭代取值

      l = ['a'a,'b','c']

      i = 0

      while i <len(l):

        print(l[i])

        i+=1 

      什么是迭代器:

        迭代取值的工具

    2.为什么要用迭代器

    迭代器

      1.优点:提供了一种不依赖索引的迭代取值方式

      2.更节省内存(每次只取一个值放到内存中使用,下次调用才会取下个值)

    缺点:

      1.不如按照索引的取值方式灵活

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

    3.如何用迭代器

      可迭代对象:str、list、tupledictset文件对象

      但凡有__iter__方法的对象都称之为可迭代对象

      迭代器对象:文件对象

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

        (关键点:调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象)

    用内置方法__next__ 可以取出迭代器的下一个值

    上面iter_d拿到由d的内容产生的迭代器

    但是当next取到最后一个值之后,继续next取值,就会报错,会抛出异常 StopIteration

    d={'k1':111,'k2':222,'k3':333}

    d={1,2,3,4,5}

    iter_d = d.__iter__()  一般__下滑线开头的方法,满足一定条件时自动触发,最好不要这么用

    可以用iter_d = iter(d) 来用,就相当于d.__iter__

    next也一样

    print(next(iter_d)) # 相当于iter_d.__next__()

    print(len(d))

    就相当于print(d.__len__())

    print(iter.d.__iter__().__iter__().__iter__() is iter_d)

    上面语句返回的是true,也就是说迭代器的iter返回值就是这个迭代器本身,只是python对于可迭代对象和迭代器对象不写两种实现方式了,所以都用相同的方法,返回都是迭代器

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

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

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

    以上三条语句的返回值都一样,都是d产生的迭代器的第一个元素

    while True:

      try:

        v = iter_d.next()

        print(v)

       except StopIteration:

        break

    print('第二次取值‘)

    #iter_d = d.__iter__()  # 没有这句的话,下面的第二次取值不会取到值,因为iter_d这个迭代器已经在上一次循环中取到末尾报异常结束了,如果不重置这个迭代器,就会继续报异常直接结束取值过程

    while True:

      try:

        v = iter_d.__next__()

        print(v)

      except StopIteration:

        break

    以上用try去捕捉异常的写法太麻烦了,其实for语句的底层机制就和上面的语句一样

    for k in d:

      print(k)

    for循环的底层原理

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

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

    3.捕捉异常结束循环

    2.生成器

    什么是生成器

    生成器就是一个自定义的迭代器

    如何得到生成器

      单反函数内出现yield关键字时,再去调用函数时不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器

    #因为用return的话会直接返回值并且结束程序的运行

    def func():

      print(‘first’)

      yield 1

      print(''second')

      yield 2

      print('third')

      yield 3

    g = func()

    print(g) #g是一个生成器对象

    res1 = next(g)

    print(res1)

    res2 = next(g)

    print(res2)

    resa3 = next(g)

    print(res3)

    next(g) # 报错,没有值可以取了

    总结 yield

    1.提供了一种自定义迭代器的解决方案

    2.yield&return

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

    不同点: return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值

    来用生成器模拟一个range函数

    def calc(start,end,step = 1):

      while start < end:

        yield start

        start += step

    a = calc(1,10,2) # 返回生成器对象

    for i in a:

    print(i) # for循环取出所有值

    3. 函数的递归调用和二分法

      递归必须满足的两个条件:

        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

    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=[1,2,3,4,5,6,7,8,9]

    def search(nums,find_num):

      if len(nums) == 0:

        print('not exist')

        return

      mid = len(nums) // 2

      if nums[mid] > find_num:

        search(nums[:mid],find_num)

      elif nums[mid]<find_num:

        search(nums[mid+1:],find_num)

      else:

        print('get it')

    search(nums,9)

  • 相关阅读:
    py笔记之循环结构
    PY学习记录#5
    PY学习记录#4
    py笔记之选择结构
    PY学习记录#3
    分享一个可以随时随地写代码的工具
    PY学习记录#2
    日记啊
    Tarjan学习笔记
    Docker commands
  • 原文地址:https://www.cnblogs.com/shanau2/p/10059392.html
Copyright © 2020-2023  润新知