python--迭代,生成

迭代和递归,最初在DNS resolution中见到过,  迭代指的A问B ,A问C,A问D .   A向上一代一代的查问

下面进入本次文章的主题

python中的迭代和生成

为什么引入迭代:

迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,

即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。

可迭代的判断:  1.用命令 isinstance([], Iterable)

               2.  如果这个对象中有__next__()方法,这个对象就是可迭代对象

注意: 字符串str,列表list,元组tuple,字典dic,集合set,文件对象 都不是可迭代对象.都没__next__方法

在for循环,就是使用__iter__方法,将其变成了可迭代对象   

list1 = [1,2,3,4]

iter_l = l.__iter__()

print(iter_l.__next__()

//////////////生成器 generator

生成器的作用: 自动实现了生成器协议,不用再调用 __iter__()方法 再去生成可迭代对象了.

生成器 generator.创建方法: 一  二

创建生成器法一 : 用 ()

生成器也是可迭代对象,所以也能使用for循环啦

g = (x*x for x in range(10))

for a in  g:   (原理 调用的next方法,不断的去next

print(a)

创建生成器法二: 关键字 yield

·         yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器

·         当你调用这个函数的时候,函数内部的代码不立刻执行 ,而是返回一个生成器对象

·         当使用for进行迭代的时候,函数中的代码才会执行

 

def createGenerator():

    for i in range(3):

        yield i * i

myGenerator = createGenerator()  #得到一个生成器对象

 

for i in myGenerator:

    print(i)

 

第二个例子(多理解):

def foo():

    print("starting...")

    while True:

        res = yield 4

        print("res:",res)

 

g = foo()

return_val = next(g)

print(return_val)

print("*"*20)

print(next(g))

 

程序执行情况:

starting...

4

********************

res: None

4

1.       g = foo()程序开始执行 : 因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

2. print(return_val)     调用next方法,foo函数开始执行,先执行foo函数中的print方法,然后进入while循环

遇到yield关键字,然后把yield想象成return,return了一个4之后,程序停止,没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,

 

4.程序执行print("*"*20),输出20*

 

5.执行第二个print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,res = yield 这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,

 

6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 4,然后程序停止,print函数输出的4就是这次return出的4.

 

关键问题  y = yield 8 怎么输出取决于send next

The value of the yield expression after resuming depends on the method which resumed the execution. If __next__()  (or .next()) is used then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.

 

yield 继续加码  关于send

send作用:1\传值给yield    \2\.__next__()一样的功能

def test():

    i = 1

    while i < 5:

        temp = yield i**2

        cc = 3

        print(temp)

        i += 1

 

t = test()

a = t.__next__()

print(a)

 

t.send('hello world')

输出内容:

1

hello world  (这是 print(temp)的结果)

分析:  1.执行yield i**2 返回给变量所以打印1

2.    t.send('hello world'yield后面的值变成'hello world,  然后是第二个next, temp = 'hello world  ……..''

 

 

猜你喜欢

转载自www.cnblogs.com/zyhe/p/10549267.html