【4858.com】魔法方法,迭代器和生成器

By admin in 4858.com on 2019年2月18日

目录:

  • 调用三个日常的函数,一般是从函数的第壹行代码初步推行,至return语句、非凡只怕具有语句执行落成,可以知道为函数执行到位。一旦函数使用已毕,函数中做的拥有工作以及保存在有个别变量中的数据都都会丢掉。下次应用该函数时,一切又都从头起首。

  • 生成器可以使得Python模仿协同程序的定义可以已毕。
    *
    协同程序:可以运维的单独函数调用,函数可以暂停或然挂起,并且在须求的时候从程序离开的地点继续或然是双重开头运转。

  • 生成器可以权且挂起函数,并保存函数的有个别变量等数据,然后下次调用的时候,从上五次中断的任务继续执行下去。

一,什么是迭代器协议

15 Python 迭代器和生成器,15python生成器

  一、生成器

练习1

In [1]: def myGen():
   ...:     print("生成器被执行!")
   ...:     yield 1
   ...:     yield 2
   ...:     

In [2]: myGenerator = myGen()

In [3]: next(myGenerator)
生成器被执行!
Out[3]: 1

In [4]: next(myGenerator)
Out[4]: 2

In [5]: next(myGenerator)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-5-fc98abb8b680> in <module>()
----> 1 next(myGenerator)

StopIteration: 

注意:当函数甘休时,抛出八个StopIteration极度。Python中的for循环会自动调用next()方法和拍卖StopIteration相当,即for循环可以对生成器发生效益。

1.迭代器协议是指:对象必须提供1个next方法,执行该措施还是回到迭代中的下一项,要么就挑起贰个StopIteration十分,以截至迭代
(只可以后后走不能往前退)

咋样是迭代 (iterable)

  字符串、列表、元组、字典、集合都足以被for循环,表明他们都是可迭代的

  可以一贯效果于for循环的目的统称为可迭代对象(Iterable)。

  能够被next()函数调用并连发再次来到下2个值的对象称为迭代器(Iterator)。

  全体的Iterable均可以通过内置函数iter()来扭转为Iterator。

  对迭代器来讲,有3个__next__()就够了。在您采纳for 和 in
语句时,程序就会自动调用即将被处理的目的的迭代器对象,然后拔取它的__next__()方法,直到监测到1个StopIteration很是。

  可迭代协议

    大家以往是从结果分析原因,能被for循环的就是“可迭代的”,但是假设正考虑,for怎么了然什么人是可迭代的吧?

    假如大家温馨写了三个数据类型,希望这一个数据类型里的东西也足以运用for被3个七个的取出来,那我们就必须满足for的须求。这些须要就称为“协议”。

  可以被迭代要满足的渴求就叫做可迭代协议。可迭代协议的定义相当简单,就是中间贯彻了__iter__【4858.com】魔法方法,迭代器和生成器。方法。

4858.com 1

 1 >>> L = [1,2,3]
 2 >>> [x**2 for x in L]
 3 [1, 4, 9]
 4 >>> next(L)
 5 Traceback (most recent call last):
 6   File "<stdin>", line 1, in <module>
 7 TypeError: 'list' object is not an iterator
 8 >>> I=iter(L)
 9 >>> next(I)
10 1
11 >>> next(I)
12 2
13 >>> next(I)
14 3
15 >>> next(I)
16 Traceback (most recent call last):
17   File "<stdin>", line 1, in <module>
18 StopIteration

View Code

  上边例子中,列表L可以被for举行巡回但是不可以被停放函数next()用来探寻下多个值,所以L是Iterable。

  L通过iter举办包装后设为I,I能够被next()用来查找下3个值,所以I是Iterator。

4858.com 2

 1 >>> L = [4,5,6]
 2 >>> I = L.__iter__()
 3 >>> L.__next__()
 4 Traceback (most recent call last):
 5   File "<stdin>", line 1, in <module>
 6 AttributeError: 'list' object has no attribute '__next__'
 7 >>> I.__next__()
 8 4
 9 >>> from collections import Iterator, Iterable
10 >>> isinstance(L, Iterable)
11 True
12 >>> isinstance(L, Iterator)
13 False
14 >>> isinstance(I, Iterable)
15 True
16 >>> isinstance(I, Iterator)
17 True
18 >>> [x**2 for x in I]    
19 [25, 36]

View Code

  ② 、课时49课后习题及答案

练习2

In [6]: for i in myGen():
   ...:     print(i)
   ...:     
生成器被执行!
1
2

2.可迭代对象:完毕了迭代器协议的靶子(如何完结:对象内部定义三个__iter__()方法)

迭代器

迭代器坚守迭代器协议:必须有所__iter__方法和__next__方法。

抱有访问生成器的能力,可以访问到生成器的值,类似于生成器的__next__方法,七个二个值三个值得去迭代,只好够根据顺序的去追寻。

特点:

4858.com 3

1 print('__next__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__
2 print('__iter__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__
3 
4 from collections import Iterator
5 print(isinstance(range(100000000),Iterator))  #验证range执行之后得到的结果不是一个迭代器

View Code

 

以生成器的不二法门贯彻斐波那契数列

In [7]: def fibs():
   ...:     a = 0
   ...:     b = 1
   ...:     while True:
   ...:         a , b = b ,a + b
   ...:         yield a
   ...:         

In [8]: for each in fibs():
   ...:     if each > 100:
   ...:         break
   ...:     print(each)
   ...:   
结果如下:  
1
1
2
3
5
8
13
21
34
55
89

3.商谈是一种约定,可迭代对象完结了迭代器协议,python的中间工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

yield from

4858.com 4

 1 def gen1():
 2     for c in 'AB':
 3         yield c
 4     for i in range(3):
 5         yield i
 6 
 7 print(list(gen1()))
 8 
 9 def gen2():
10     yield from 'AB'
11     yield from range(3)
12 
13 print(list(gen2()))

View Code

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

推导式(列表、字典、集合

  • 1.列表推导式

In [1]: a = [i for i in range(100) if not( i % 2 )and i % 3]

In [2]: print(a)
[2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]

注意:上述列表推导式求得是100以内,能被2整除,但不只怕被3整除的富有整数。

  • 2.字典推导式

In [3]: b = {i:i % 2 == 0 for i in range(10)}

In [4]: print(b)
{0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}
  • 3.凑合推导式

In [5]: c = {i for i in [1,1,2,3,3,4,5,5,5,5,7,8,9,41]}

In [6]: print(c)
{1, 2, 3, 4, 5, 7, 8, 9, 41}
  • 4.生成器推导式

In [7]: e = (i for i in range(10))

In [8]: e
Out[8]: <generator object <genexpr> at 0x000001B8579DBF10>

注意:generator就是生成器的情趣,用一般的小括号括起来的难为生成式推导式,表达如下:

In [11]: next(e)
Out[11]: 0

In [12]: next(e)
Out[12]: 1

In [13]: next(e)
Out[13]: 2

In [14]: next(e)
Out[14]: 3

In [15]: next(e)
Out[15]: 4

In [16]: next(e)
Out[16]: 5
for循环打印出剩余的:
In [17]: for each in e:
    ...:     print(each)
    ...:     
6
7
8
9
  • 生成器推导式假设作为函数的参数,可以直接写推导式,不用加小括号:

In [1]: sum(i for i in range(100) if i % 2)
Out[1]: 2500

二,for循环的本色

生成器

  1.生成器函数:常规函数定义,然而,使用yield语句而不是return语句重返结果。yield语句一次回到三个结实,在各种结果中间,挂起函数的场地,以便下次重它离开的地方继续执行

  2.生成器表达式:类似于列表推导,可是,生成器再次回到按需爆发结果的2个对象,而不是几回营造2个结实列表

 

生成器Generator:

  本质:迭代器(所以自带了__iter__方法和__next__方法,不须要大家去贯彻)

  特点:惰性运算,开发者自定义

生成器函数

  2个蕴含yield关键字的函数就是二个生成器函数。yield可以为大家从函数中再次回到值,可是yield又差别于return,return的举办代表程序的甘休,调用生成器函数不会获取再次来到的现实性的值,而是拿到1个可迭代的目的。每一次拿走这些可迭代对象的值,就能牵动函数的实施,获取新的重回值。直到函数执行完毕。

  仅仅拥有生成某种东西的能力,假使不用__next__措施是赢得不到值得。

  创造2个生成器函数

4858.com 5

 1 >>> def scq():
 2     print("11")
 3        # 当函数代码块中遇到yield关键字的时候,这个函数就是一个生成器函数
 4     yield 1
 5     print("22")
 6     yield 2
 7     print("33")
 8     yield 3
 9 
10 
11 # 把生成器赋值给一个对象
12 
13 >>> r = scq()
14 
15 # 查看r的苏剧类型并且输出r的值
16 
17 >>> print(type(r),r)
18 <class 'generator'> <generator object scq at 0x000001F117D8DF10> 
19 
20 # 当执行生成器的__next__的时候,代码会按照顺序去执行,当执行到yield时会返回并
21 # 提出,yield后面的值就是返回值,然后记录代码执行的位置,并退出
22 
23 >>> ret = r.__next__()
24 11
25 
26 # 第二次执行的时候会根据上次代码执行的位置继续往下执行
27 
28 >>> ret = r.__next__()
29 22
30 >>> ret = r.__next__()
31 33
32 
33 # 如果__next__获取不到值的时候就会报StopIteration错误
34 
35 >>> ret = r.__next__()
36 Traceback (most recent call last):
37   File "<stdin>", line 1, in <module>
38 StopIteration

View Code

  利用生成器创设八个range

4858.com 6

 1 # 创建一个生成器函数,函数名是range,n是传入的参数,也是输出的数的最大值
 2 def range(n):
 3     # 默认从0开始
 4     start = 0
 5     # 进入while循环,如果最小值小于最大值就进入循环
 6     while start < n:
 7         # 第一次返回start,下面代码不执行
 8         yield start
 9         # 第二次进来的时候start = start + 1,然后进入下一次循环
10         start += 1
11 
12 # 停止的参数为5
13 obj = range(5)
14 # 第一个数赋值给n1
15 n1 = obj.__next__()
16 # 第二个数赋值给n2
17 n2 = obj.__next__()
18 # 第三个数赋值给n3
19 n3 = obj.__next__()
20 # 第四个数赋值给n4
21 n4 = obj.__next__()
22 # 第五个数赋值给n5
23 n5 = obj.__next__()
24 
25 # 输出这五个数的值
26 print(n1,n2,n3,n4,n5)
27 
28 # 执行结果
29 
30 C:\Python35\python.exe F:/Python_code/sublime/Week5/Day03/s1.py
31 0 1 2 3 4
32 
33 Process finished with exit code 0

View Code

  生成器监听文件输入的例题

4858.com 7

 1 import time
 2 
 3 
 4 def tail(filename):
 5     f = open(filename)
 6     f.seek(0, 2) #从文件末尾算起
 7     while True:
 8         line = f.readline()  # 读取文件中新的文本行
 9         if not line:
10             time.sleep(0.1)
11             continue
12         yield line
13 
14 tail_g = tail('tmp')
15 for line in tail_g:
16     print(line)

View Code

 总计移动平均值(1)

4858.com 8

 1 def averager():
 2     total = 0.0
 3     count = 0
 4     average = None
 5     while True:
 6         term = yield average
 7         total += term
 8         count += 1
 9         average = total/count
10 
11 
12 g_avg = averager()
13 next(g_avg)
14 print(g_avg.send(10))
15 print(g_avg.send(30))
16 print(g_avg.send(5))

View Code

 统计移动平均值(2)预激协程的装饰器

4858.com 9

 1 def init(func):  #在调用被装饰生成器函数的时候首先用next激活生成器
 2     def inner(*args,**kwargs):
 3         g = func(*args,**kwargs)
 4         next(g)
 5         return g
 6     return inner
 7 
 8 @init
 9 def averager():
10     total = 0.0
11     count = 0
12     average = None
13     while True:
14         term = yield average
15         total += term
16         count += 1
17         average = total/count
18 
19 
20 g_avg = averager()
21 # next(g_avg)   在装饰器中执行了next方法
22 print(g_avg.send(10))
23 print(g_avg.send(30))
24 print(g_avg.send(5))

View Code

列表推导式和生成器表明式

4858.com 10

 1 #老男孩由于峰哥的强势加盟很快走上了上市之路,alex思来想去决定下几个鸡蛋来报答峰哥
 2 
 3 egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析
 4 
 5 #峰哥瞅着alex下的一筐鸡蛋,捂住了鼻子,说了句:哥,你还是给我只母鸡吧,我自己回家下
 6 
 7 laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式
 8 print(laomuji)
 9 print(next(laomuji)) #next本质就是调用__next__
10 print(laomuji.__next__())
11 print(next(laomuji))

View Code

一、生成器

补充:

运行环境:Anaconda3 中的Jupyter
QTConsole,还足以应用PyCharm大概python3自带的IDLE(适合新手学习运用)
下载地址:
<a
href=”;

python学习沟通群:463024091
作者qq:1070457631

循环全体目标,全都是拔取迭代器协

各样推导式详解

  推导式的老路

    以前大家早就学习了最不难易行的列表推导式和生成器表明式。可是除此之外,其实还有字典推导式、集合推导式等等。

    上边是三个以列表推导式为例的推导式详细格式,同样适用于别的推导式。

4858.com 11

1 variable = [out_exp_res for out_exp in input_list if out_exp == 2]
2   out_exp_res:  列表生成元素表达式,可以是有返回值的函数。
3   for out_exp in input_list:  迭代input_list将out_exp传入out_exp_res表达式中。
4   if out_exp == 2:  根据条件过滤哪些值可以。

View Code

列表推导式

  例一:30以内享有能被3整除的数

4858.com 12

1 multiples = [i for i in range(30) if i % 3 is 0]
2 print(multiples)
3 # Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

View Code

  例二:30以内有着能被3整除的数的平方

4858.com 13

1 def squared(x):
2     return x*x
3 multiples = [squared(i) for i in range(30) if i % 3 is 0]
4 print(multiples)

View Code

  例三:找到嵌套列表中名字含有多个‘e’的装盛名字

4858.com 14

1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
2          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
3 
4 print([name for lst in names for name in lst if name.count('e') >= 2])  # 注意遍历顺序,这是实现的关键

View Code

字典推导式

  例一:将一个字典的key和value对调

4858.com 15

1 mcase = {'a': 10, 'b': 34}
2 mcase_frequency = {mcase[k]: k for k in mcase}
3 print(mcase_frequency)

View Code

  例二:合并大小写对应的value值,将k统十分之一小写

4858.com 16

1 mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
2 mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()}
3 print(mcase_frequency)

View Code

聚集推导式

  例:计算列表中各样值的平方,自带去重效益

4858.com 17

1 squared = {x**2 for x in [1, -1, 2]}
2 print(squared)
3 # Output: set([1, 4])

View Code

练习题:

  例1:  过滤掉长度小于3的字符串列表,并将剩余的转换到大写字母

  例2:  求(x,y)其中x是0-5之内的偶数,y是0-5时期的奇数组成的元祖列表

  例3:  求M中3,6,9结缘的列表M = [[1,2,3],[4,5,6],[7,8,9]]

4858.com 18

1 1.[name.upper() for name in names if len(name)>3] 
2 2.[(x,y) for x in range(5) if x%2==0 for y in range(5) if y %2==1] 
3 3. [row[2] for row in M]

View Code

 

总结:

  1.把列表解析的[]换到()拿到的就是生成器表明式

  2.列表解析与生成器表明式都以一种便民的编程格局,只可是生成器表明式更省去内存

  3.Python不但利用迭代器协议,让for循环变得越来越通用。半数以上内置函数,也是利用迭代器协议访问对象的。例如,
sum函数是Python的松手函数,该函数使用迭代器协议访问对象,而生成器完毕了迭代器协议,所以,大家得以直接这样总计一多元值的和:

4858.com 19

1 sum(x ** 2 for x in range(4))
2 
3 # 而不用多此一举的先构造一个列表:
4 
5 sum([x ** 2 for x in range(4)]) 

View Code

可迭代对象:

  拥有__iter__方法

  特点:惰性运算

  例如:range(),str,list,tuple,dict,set

迭代器Iterator:

  拥有__iter__方法和__next__方法

  例如:iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o

生成器Generator:

  本质:迭代器,所以具有__iter__方法和__next__方法

  特点:惰性运算,开发者自定义

应用生成器的助益:

1.延迟计算,一遍回到一个结出。约等于说,它不会五次变动全部的结果,那对于大数据量处理,将会十三分实用。

**2.增进代码可读性**

4858.com 20

1 #列表解析
2 sum([i for i in range(100000000)])#内存占用大,机器容易卡死
3  
4 #生成器表达式
5 sum(i for i in range(100000000))#几乎不占内存

View Code

生成器相关的面试题

  生成器在编程中发生了成千上万的法力,善用生成器能够扶持我们缓解广大复杂的难题

  除此之外,生成器也是面试题中的重点,在做到部分功力之外,人们也想出了好多魔性的面试题。
  面试题(1)

4858.com 21

 1 def demo():
 2     for i in range(4):
 3         yield i
 4 
 5 g=demo()
 6 
 7 g1=(i for i in g)
 8 g2=(i for i in g1)
 9 
10 print(list(g1))
11 print(list(g2))

View Code

  面试题(2)

4858.com 22

 1 def add(n,i):
 2     return n+i
 3 
 4 def test():
 5     for i in range(4):
 6         yield i
 7 
 8 g=test()
 9 for n in [1,10]:
10     g=(add(n,i) for i in g)
11 
12 print(list(g))

View Code

  tail&grep

4858.com 23

 1 def demo():
 2     for i in range(4):
 3         yield i
 4 
 5 g=demo()
 6 
 7 g1=(i for i in g)
 8 g2=(i for i in g1)
 9 
10 print(list(g1))
11 print(list(g2))
12 
13 复制代码
14 复制代码
15 
16 def add(n,i):
17     return n+i
18 
19 def test():
20     for i in range(4):
21         yield i
22 
23 g=test()
24 for n in [1,10]:
25     g=(add(n,i) for i in g)
26 
27 print(list(g))
28 
29 复制代码
30 复制代码
31 
32 import os
33 
34 def init(func):
35     def wrapper(*args,**kwargs):
36         g=func(*args,**kwargs)
37         next(g)
38         return g
39     return wrapper
40 
41 @init
42 def list_files(target):
43     while 1:
44         dir_to_search=yield
45         for top_dir,dir,files in os.walk(dir_to_search):
46             for file in files:
47                 target.send(os.path.join(top_dir,file))
48 @init
49 def opener(target):
50     while 1:
51         file=yield
52         fn=open(file)
53         target.send((file,fn))
54 @init
55 def cat(target):
56     while 1:
57         file,fn=yield
58         for line in fn:
59             target.send((file,line))
60 
61 @init
62 def grep(pattern,target):
63     while 1:
64         file,line=yield
65         if pattern in line:
66             target.send(file)
67 @init
68 def printer():
69     while 1:
70         file=yield
71         if file:
72             print(file)
73 
74 g=list_files(opener(cat(grep('python',printer()))))
75 
76 g.send('/test1')
77 
78 协程应用:grep -rl /dir

View Code

 

Python 迭代器和生成器,15python生成器
什么是迭代 (iterable) 字符串、列表、元组、字典、集合
都得以被for循环,表明他俩 都是可迭代的…

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

for循环可以遍历(字符串,列表,元组,字典,集合,文件对象),可是那个都不是可迭代对象,只不过在for循环式,调用了他们之中的__iter__措施,把她们成为了可迭代对象。

生成器的读书并不关乎魔法方法,甚至它巧妙地逃脱了类和对象,仅通过普通地函数就可以已毕了。

下一场for循环调用可迭代对象的__next__主意去取值,而且for循环会捕捉StopIteration万分,以平息迭代。

生成器其实是迭代器的一种完毕。

 

  • 生成器的阐明一边是为着使得Python更为简单,因为,迭代器必要我们友好去定义八个类和落到实处相关的情势,而生成器则只要求在一般的函数中增进一个yield语句即可。
  • 一面,生成器的表明,使得Python模仿协同程序的定义可以贯彻。所谓协同程序,就是足以运作得独立函数调用,函数可以暂停大概挂起,并在急需得时候从程序离开得地点继续恐怕再一次初步。
#:用while去模拟for循环做的事情
l=[1,2,3,4,5,6]
diedai_l=l.__iter__()
while True:
    try:
        print(diedai_l.__next__())
    except StopIteration:#捕捉到异常后退出
        break

对此调用壹个平凡的Python函数,一般是从函数的率先行代码开头举办,截至于return语句、非凡、只怕函数全部语句执行已毕。一旦函数将控制权交还给调用者,就表示整个停止。函数中做的富有工作以及保存在一些变量中的数据都将遗失。再一次调用这一个函数时,一切将上马创制。

 

Python是通过生成器来落到实处类似于协同程序的概念:生成器可以一时挂起函数,并保存函数的有的变量等数据,然后在重复调用它的时候,从上次废然则返的职位继续执行下去。

三,怎么着查看是或不是可迭代的大概不是迭代器

举个例证:

 

 

from collections import Iterable
from collections import  Iterator
a=range(10)
a=range(10)
print(isinstance(a,Iterator))#查看是不是迭代器
print(isinstance(a,Iterable))#查看是不是可迭代的
>>> def myGen():
    print("生成器被执行!")
    yield 1
    yield 2


>>> myG = myGen()
>>> next(myG)
生成器被执行!
1
>>> next(myG)
2
>>> next(myG)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    next(myG)
StopIteration

 

正如大家所见,当函数停止的时候,2个StopIteration非凡就会抛出。由于Python的for循环会自动调用next()方法和拍卖StopIteration很是,所以for循环当然也是足以对生成器暴发功效的:

四,什么是生成器

>>> for i in myGen():
    print(i)


生成器被执行!
1
2

可以知晓为一种数据类型,那种数据类型自动完毕了迭代器协议(其他的数据类型要求调用本人松开的__iter__措施),所以生成器就是可迭代对象

像后边介绍的斐波那契的事例,也可以用生成器来促成:

五,生成器在python中的表现格局

>>> def fibs():
    a = 0
    b = 1
    while True:
        a,b = b,a + b
        yield a



>>> for each in fibs():
    if each > 100:
        break
    print(each)


1
1
2
3
5
8
13
21
34
55
89

4858.com , 

事到近来,你应该已经很好的左右了列表推到式子(并不曾,哭唧唧),那上面这么些列表推导式表明的是啥意思:

1.生成器函数:常规函数定义,不过,使用yield语句而不是return语句再次回到结果。yield语句两回回到二个结实,在种种结果中间,挂起函数的场地,以便下次重它离开的地点继续执行

>>> a = [i for i in range(100) if not(i%2) and i%3]

 

实际上边那几个列表推导式求得就是100以内,能被2整除但无法被3整除的富有整数:

2.生成器表达式:好像于列表推导,不过,生成器再次回到按需爆发结果的一个目的,而不是三次营造三个结果列表

>>> a
[2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]

 

python3除了有列表推导式,还有字典推导式:

六,生成器的独到之处

>>> b = {i:i%2 == 0 for i in range(10)}
>>> b
{0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}

Python使用生成器对延期操作提供了扶助。所谓延迟操作,是指在急需的时候才发生结果,而不是及时发生结果。那也是生成器的机要利益。

还有集合推导式:

七,生成器函数

>>> c = {i for i in [1,1,2,3,3,4,5,5,5,6,7,7,8]}
>>> c
{1, 2, 3, 4, 5, 6, 7, 8}

 

这是还是不是有字符串推导式和元组推导式呢?试一试:

4858.com 244858.com 25

>>> d = "I love zww"
>>> d
'I love zww'
#计算移动平均值
def wrap(func):
    def inner(*args,**kwargs):
        ret = func()
        next(ret)
        return  ret
    return inner
@wrap
def averanger():
    total=0
    day=0
    avrage=0
    while True:
        day_nub=yield  avrage
        total+=day_nub
        day+=1
        avrage=total / day
avg=averanger()
print(avg.send(15))
print(avg.send(22))

喔,不行,因为在双引号内,全数的东西都改成了字符串,所以不存在字符串推导式,那元组推导式呢?

View Code

>>> e = (i for i in range(10))
>>> e
<generator object <genexpr> at 0x000002001EC4CB88>

八,生成器表明式

啊?如同这么些不是哪些推导式嘛。generator,多么熟习的单词,就是生成器嘛!没错用普通小括号括起来的正是生成器推导式,来说爱他美下:

 

>>> next(e)
0
>>> next(e)
1
>>> next(e)
2
>>> next(e)
3
>>> next(e)
4
#列表解析
sum([i for i in range(100000000)])#内存占用大,机器容易卡死

#生成器表达式
sum(i for i in range(100000000))#几乎不占内存

用for语句把剩余的给打印出来:

 

>>> for each in e:
    print(each)


5
6
7
8
9

九,生成器总括

还有二个特色更牛,生成器推导式如若作为函数的参数,可以直接写推导式,而不用加小括号:

1.是可迭代对象

>>> sum(i for i in range(100) if i % 2)
2500

 

【伸张阅读】增加你的 Python:解释 yield 和
Generators(生成器)

2.兑现了延期计量,省里存,

 

 

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

3.生成器本质和此外的数据类型一样,都是兑现了迭代器协议,只不过生成器附加了三个延迟总计省外存的益处,其余的可迭代对象可没有这一点便宜,

二 、课时49课后习题及答案

 

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

  • 语法上和函数类似:生成器函数和常规函数大概是一致的。它们都以选拔def语句举行定义,差距在于,生成器使用yield语句再次回到一个值,而常规函数使用return语句再次回到3个值
  • 活动完成迭代器协议:对于生成器,Python会自动完毕迭代器协议,以便利用到迭代背景中(如for循环,sum函数)。由于生成器自动已毕了迭代器协议,所以,大家可以调用它的next方法,并且,在尚未值可以回到的时候,生成器自动发出StopIteration很是
  • 动静挂起:生成器使用yield语句重临多个值。yield语句挂起该生成器函数的气象,保留充分的音信,以便之后从它离开的地点继续执行

4858.com 26

 

4858.com 27

4858.com 28

4858.com 29

4858.com 30

4858.com 31

4858.com 32

 4858.com 33

 预见后文怎么样?请君耐心等待.

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有