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

    以下都是我自学Python整理的笔记,以便帮助学习。

    容器(container)

      1.容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个的迭代获取,可以用in,not in关键字判断元素是否在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例并不是把所有的元素存在内存,比如迭代器和生成器对象)在python中,常见的容器对象有:list,set,dict,tuple,str...

      2.尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是**可迭代对象**赋予了容器这种能力,当然并不是所有的容器都是可迭代的,比如:[Bloom filter],虽然Bloom filter可以用来检测某个元素是否包含在容器中,但是并不能从容器中获取其中的每一个值,因为Bloom filter压根就没把元素存储在容器中,而是通过一个散列函数映射成一个值保存在数组中。

    可迭代对象(iterable)

      1.许多容器都是可迭代对象,但也有很多不是容器的对象也是可迭代对象,比如处于打开状态的files,socket等。

      2.可迭代对象都具有__iter__函数,并且可迭代对象通过iter()函数会返回一个迭代器,迭代器内部具有一个状态,该状态用于记录当前迭代所在的位置方便下一次迭代。

      3.迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。

    迭代器(iterator)

      1.迭代器是一种带状态的对象,它能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__方法的对象都是迭代器,__iter__返回迭代器本身,__next__返回容器中的下一个值,当遍历到最后一个值,没有元素的时候会抛出StopIteration异常。

      2. itertools函数返回的都是迭代器对象。

      3.迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

      4.三种常见的迭代器:

      (1)无限迭代器,这个可以理解成一条无限延长的直线。

       itertools模块下的count(start)函数,star为起点。

    help(itertools.count)#查看帮助文档 
    count(start=0, step=1) --> count object | Return a count object whose .__next__() method returns consecutive values. def count(firstval=0, step=1): | x = firstval | while 1: | yield x | x += step

    例子:

    import itertools
    >>> counter = itertools.count(start=2)
    >>> next(counter)
    2
    >>> next(counter)
    3
    >>> next(counter)
    4

     (2)通过一个有限序列生成无限迭代器,这个可以理解为是一个圆,无限遍历。

       itertools下的cycle(iterable)函数,参数是一个可迭代对象。

    help(itertools.cycle)
    cycle(iterable) --> cycle object
     |  Return elements from the iterable until it is exhausted.
     |  Then repeat the sequence indefinitely.
     #从可迭代对象取出所有的元素然后无限循环

    例子:

    >>> from itertools import cycle
    >>> colors = cycle(['red','white','blue'])
    >>> next(colors)
    'red'
    >>> next(colors)
    'white'
    >>> next(colors)
    'blue'
    >>> next(colors)
    'red'
    >>> next(colors)
    'white'

     (3)有限迭代器,其实就是无限迭代器中截取一段序列。

       itertools下的islice(iterable, start, stop[, step])

       iterable为可迭代对象,start为起点,不给start值时,默认从0开始,给值时会默认从起点的下一个元素开始遍历,stop为终点,step为步长。

    help(itertools.islice)
    class
    islice(builtins.object) | islice(iterable, stop) --> islice object | islice(iterable, start, stop[, step]) --> islice object #返回一个迭代器,iterable可迭代对象,start如果不设置为0,设置了会默认从start下一个元素开始遍历,stop终止,step步长。

    例子:

    >>> from itertools import islice
    >>> num = cycle((1,2,3))
    >>> limited = islice(num,0,4)
    >>> next(limited)
    1
    >>> next(limited)
    2
    >>> next(limited)
    3
    >>> next(limited)
    1
    >>> next(limited)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration

    生成器(generator)

      1.生成器是一种特殊的迭代器,不过这种迭代器更加优雅。需要一个yiled关键字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。

      2.生成器有延迟作用,就是有需要的时候才会生产数据,不是立即产生结果。

      生成器只能遍历一次。

      4.两种方法得到生成器:

      (1)定义生成器函数,返回值用yield而不是return,yield和return最本质的区别在于return会终止函数,不会保留函数中的变量,再次如果再次调用函数时从头开始;而yield相当于在是冻结函数,给了函数一个状态,让他暂时挂起保留此次调用的变量,下一次继续这个位置调用。

    看例子:

    #用return
    def
    func(var): while var > 0: print(var) return var var -= 1 d = func(10) print(type(d)) 10 <class 'int'>
    #用yield
    def func(var):
        while var > 0: 
            yield var
            #return var
            var -= 1
            
    d = func(10)
    print(type(d))
    
    <class 'generator'>#type看到d是一个生成器

    #所以我们可以对d进行for循环遍历
    for i in d:
      print(i)
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1

      (2)生成器表达式:把列表推导式的[ ]改成( )

        使用生成器表达式取代列表推导式可以同时节省 cpu 和 内存(RAM)。

        gen = (i for i in range(10))

    gen = (i for i in range(10))
    print(type(gen))
    for var in gen:
        print(var)
    <class 'generator'>
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

      

  • 相关阅读:
    Android studio 克隆分支
    香蕉派 banana pi BPI-M3 八核开源硬件开发板
    Visual F# Power Tools 简单介绍
    win764bit系统plsqldeveloper11连接oracle11g64bit配置方法
    cocos2d-x 模态对话框的实现
    《AndroidStudio每日一贴》2.高速查看项目中近期的变更
    Android百日程序 开篇章:Intent打开网页
    Linux应用server搭建手冊—Weblogic服务域的创建与部署
    HDU 5623 KK's Number(DP)
    JAVA之堆内存和栈内存的差别
  • 原文地址:https://www.cnblogs.com/kmnskd/p/9728881.html
Copyright © 2011-2022 走看看