python学习笔记05

生成器,迭代器

生成器

1. 列表生成式

1
2
3
4
5
6
7
def f(n):
return n*n*n

a = [f(x) for x in range(10)] # 执行结果: [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
b = [x**2 for x in range(5)] # 执行结果: [0, 1, 4, 9, 16]
print(b)
print(a)

就是这个格式

###2. 赋值,python特有

1
2
3
4
5
t = ('123', 8)
a, b = t # 相当于a = t[0],b = t[1]
c, d, e = 3, 4, 45
print(a, b) # 执行结果:123 8
print(c, d, e) # 执行结果:3 4 45

3. 生成器

生成器两种创建方式

1.(x*2 for x in range(1000))
2.yield 创建

  • 一:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a = (x*2 for x in range(5))          # a为一个生成器对象
    print(a)
    print(a.__next__()) # ——defname——特殊方法调用,尽量少用。执行结果:0

    print(next(a)) # next()内置函数,等价于a.__next__.执行结果:2
    print(next(a)) # 执行结果:4
    print("*".center(50, '*'))
    for i in a:
    print(i) # 执行结果:6 , 8

之所以叫生成器是因为在获得一个生成器对象后,内存中并没有立即存入内容,而是在使用的时候实时的计算出所产生的内容,比如如果生成10000000000个数字,内存根本就放不下,这时候使用生成器可以完成任务

  • 二:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def foo():               # 看似是函数,其实是定义了一个生成器
    print('ok')
    yield 1 # 运行到yield语句时会停止运行,并返回yield 后面的内容
    print('ok2')
    yield 2
    print("ok3")
    yield 3


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

    print(next(g)) # 运行结果:ok,1......ok是执行到生成器内部的print语句时的表示,1:是返回了yield后的内容

    next(g) # 运行结果:ok2
    next(g) # 运行结果:ok3

通过next()方法执行生成器中的代码

4. 生成器的应用

  • 费布那切数列

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # for之后跟可迭代对象
    # 可迭代对象:内部有__inter__方法
    # for i in [1,2,3]:

    def fib(max):
    n, before, after = 0, 0, 1

    while n < max:
    yield after # 停止并返回。
    before, after = after, before+after
    n += 1

    g = fib(10)

    for i in g: # 生成器为可迭代对象,迭代一次执行一次,并获得返回值。
    print(i)
  • send()方法,向生成器传送数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # send函数
    def bar():
    print('ok1')
    count = yield 1

    print(count)
    print('ok2')
    yield 2

    b = bar()
    b.send(None) # 相当于next(b),这条语句,相当于生成器执行到yield 1
    # next(b)
    b.send('d#########') # 将数据传给count并继续执行到yield 2
    ############执行结果############
    ok1
    d#########
    ok2
  • 伪并发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import time
    def movie():
    n = 1
    while n < 100:
    print('我在看电影!%d' % n)
    yield
    time.sleep(1)
    n += 1
    def music():
    n = 1
    while n < 100:
    print('我在听音乐!%d' % n)
    yield
    time.sleep(1)
    n += 1
    mv = movie()
    mc = music()
    for i in range(100): # 两个yield交替执行。。其实把两个生成器换成两个函数也未尝不可呀。。。。。。吐槽。。
    next(mv)
    next(mc)

迭代器

生成器都是迭代器
迭代器 1.有iter方法,2.有next方法

1
2
li = [1, 2, 3, 4]
d = iter(li) # iter()函数返回了一个迭代器对象

for循环内部三件事
1.调用可迭代对象iter方法返回一个迭代器对象
2.调用迭代对象的next方法
3.处理stopiteration

1
2
3
4
5
from collections import Iterator, Iterable

print(isinstance([1, 2], list))
print(isinstance([1, 2], Iterable)) # 是否是可迭代对象true
print(isinstance([1, 2], Iterator)) # 是否是迭代器 false

0%