程序员python编程:如何使用生成器IT技术构造出动态列表?

python的列表可以直接list=[1,2,3,4,5]这样直接放入我们想要放入的数据,还可以通过动态方式生成列表

举例:

程序员python编程:如何使用生成器IT技术构造出动态列表?

该程序就是动态生成了一个列表,运行原理就是,从0到9进行循环,然后乘以2被当作元素放入列表中,所以列表是[0,2,4,6,8,10,12,14,16,18]

如果我们不通过动态列表的方式来生成这个列表,那么只能通过下面的程序来列表

程序员python编程:如何使用生成器IT技术构造出动态列表?

程序员python编程:如何使用生成器IT技术构造出动态列表?

这个程序只是乘以了2,其实还可以做很多复杂的工作,比如下面的程序

程序员python编程:如何使用生成器IT技术构造出动态列表?

可以在前面执行一个程序fun(i),当然不成用


用动态方式生成的列表是一下子都生成了,就是说[i for i in range(10000)],这个程序为了形成列表会循环10000次,然后生成列表,这个速度会很慢,而且我们可能有时只需要列表中的前20哥数据,而20之后的用不到,这就造成了资源内存的浪费。

有没有一种方法就是列表中的数据什么时候用什么时候生成,就是说同样是10000数据,我只用到前20那么就先生成前20的数据,后面的没有用那么就先不生成,那么这个列表实际只占用了20个存储空间。

要想生产成这样的列表很简单,只需要将[]改成()即可,这就是生成器,比如

程序员python编程:如何使用生成器IT技术构造出动态列表?

这就形成了一个列表,表面上这个列表是有10000个元素,可实际上这个列表中并没有任何的元素,因为我们还么有使用这个列表,没有使用他就不会生成,如果使用的话,使用到哪就生成到哪

而且使用的时候必须只能从索引为0开始使用,也就是从第一位开始逐渐往后生成,不可以直接调到其它位置使用,比如:

程序员python编程:如何使用生成器IT技术构造出动态列表?

注意一个生成器(下面程序是list)的光标只能往下走,不能往前走,举例:

程序员python编程:如何使用生成器IT技术构造出动态列表?

该程序生成了一个生成器,其中第一个循环对其进行遍历,因为是初次遍历,所以肯定是从索引0开始的,第二次进行遍历,因为生成器的光标只能往下走,所以第二次的遍历并不是从头开始遍历,而是继续当前光标进行遍历,接下来输出next也是接着当前的坐标进行遍历。

注意a,b=b,a+b的理解方式

不是a=b

b=a+b

程序员python编程:如何使用生成器IT技术构造出动态列表?

t[1]中的a+b的a还是原来的a,不是t[0]


动态列表只用一句话就可以实现:

程序员python编程:如何使用生成器IT技术构造出动态列表?

但是这种列表实现的列表只能是简单的,要想实现复杂的,就这种方法就不行了,必须要用生成器函数来完成

yield详解

一个生成器函数的定义很像一个普通的函数,除了当它要生成一个值的时候,使用yield关键字而不是return。如果一个def的主体包含yield,这个函数会自动变成一个生成器(即使它包含一个return)

每当生成器被调用的时候,它会返回一个值给调用者。在生成器内部使用yield来完成这个动作,例如yield 6。为了记住yield到底干了什么,最简单的方法是把它当作专门给生成器函数用的特殊的return

yield函数有什么用呢?当一个生成器函数调用yield,生成器函数的状态会被冻结,所有的变量的值会被保留下来,下一行要执行的代码的位置也会被记录,直到再次调用next()。一旦next()再次被调用,生成器函数会从它上次离开的地方开始。如果永远不调用next(),yield就一直记录原来的文字。

举例:

程序员python编程:如何使用生成器IT技术构造出动态列表?

程序员python编程:如何使用生成器IT技术构造出动态列表?

首先每调用一次fun()就会生成一个动态列表,所以list和list1不是同一个动态列表,这个动态列表的全部内容是["huan","feng","de","bian","cheng","ri","ji"]这个不是一次生成的,而是每调用一次动态列表,迭代器会往下执行,知道执行到yield,此时程序停止,然后生成一个列表元素,我们就可以获取到了

在yield函数中return的作用异常,当执行到return的时候,会把它当作异常返回

程序员python编程:如何使用生成器IT技术构造出动态列表?

异常处理:

程序员python编程:如何使用生成器IT技术构造出动态列表?

yield总结

yield功能有二,一个是返回参数,一个是接收参数

二者的功能顺序是第一返回参数(next),第二是执行接收参数(send)

我们在执行程序的时候,如果第一个使用的是yield返回参数的方法,那么下面还可以使用yield的接收参数的方法,如果第一个使用的是yield的send方法,那么就表示略过yield的返回参数方法,对于第一个yield不能跳过next方法

具体过程是:

动态列表生成之后,我们可以调用next方法,获取列表yield返回的数据,也可以调用send方法传递给yield数据。

情况分为两种:调用next,或调用send

当我们首先调用next方法的时候yield就会返回列表数据,并且动态列表会在当前yield停止,等待着send方法给他发送参数

如果给他发送send了参数,当前yield就会获取到参数,并且往下执行,直到下一个yield停止,等待着next方法获取它的数据

如果没有send发送参数,而是继续调用next方法,那么就表示接收参数被省略,则程序往下执行直到下一个yield,此时这个下一个yield会将它的数据返回给这个参数,然后这个yield等待着send方法,周而复始的运行

当我们首先调用send方法的时候(返回参数就被省略)yield就会获取到数据,程序会往下执行直到下一个yield

代码演示:

演示—:全部都是next方法,也就是说所有的返回数据过程全部省略

程序员python编程:如何使用生成器IT技术构造出动态列表?

过程分析:第一个next会执行返回数据获取到11,输出11(因为没有send方法,所以获取数据环节全部省略)

第二个next会执行返回数据获取到22,输出22

第三个next会执行返回数据获取到11,输出11

程序员python编程:如何使用生成器IT技术构造出动态列表?

过程分析执行next会获取返回数据11,下一个还是next表示yield“11”的获取数据被省略,此时程序停止在yield“11”,又运行next则返回数据22,此时程序停止在yield“22”,下面send(“huan”)表示使用yield“22”的传递参数方法将huan传递给他,他复制给a,然后往下执行输出a,然后堵塞到yield “33”,等待next或者send

迭代器

能够被for循环的就是迭代对象,比如集合,元组,列表,字典,还有生成器

可以使用isinstance方法来判断一个对象是否是可迭代的:Iterable

程序员python编程:如何使用生成器IT技术构造出动态列表?

生成器不但可以作用于for循环,还可以被next函数不断调用并返回下一个值,直到最后抛出异常表示无法返回下一个值

能够被next函数调用返回下一个值的对象称为迭代器:Iterator

可以通过isinstance来判断一个是否是迭代器

程序员python编程:如何使用生成器IT技术构造出动态列表?

把可迭代的但是不是迭代器的转变成迭代器可以使用iter()方法

程序员python编程:如何使用生成器IT技术构造出动态列表?

生成器都是迭代器,因为生成器都有next方法

变成迭代器就可以使用next方法来操作了

在python3中range(10)就是一个迭代器,而2中不是,2中直接是[0,1,2,3,4,5,6,7,8,9]

当我们for遍历迭代器的时候,内部实际就是使用next方法来操作的

遍历文件的时候,直接 for ff in f这个之所以快就是因为是应用了迭代器,

相关推荐