python高级特性(生成器,迭代器区别)

I guess it comes down to a simple choice: get busy living or get busy dying.

1、切片

倒数第一个元素的索引是-1
取后10个数:L[-10:]

2、迭代

  • dict: for value in d.values(), for k, v in d.items()
  • from collections import Iterable
    isinstance('abc', Iterable) # str是否可迭代
  • for i, value in enumerate(['A', 'B', 'C']):
    print(i, value)

3、列表生成式

  • list(range(1, 11))
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  • [m + n for m in 'ABC' for n in 'XYZ']

  • import os # 导入os模块
    [d for d in os.listdir('.')] # os.listdir可以列出文件和目录

  • success: [x for x in range(1, 11) if x % 2 == 0]
    error: [x for x in range(1, 11) if x % 2 == 0 else 0]

  • success: [x if x % 2 == 0 else -x for x in range(1, 11)]
    [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
    error: [x if x % 2 == 0 for x in range(1, 11)]

4、生成器

一边循环一边计算的机制,称为生成器:generator, generator保存的是算法, 可迭代

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

  • g = (x * x for x in range(10))
    for n in g:
    print(n)

函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

>>> def fib(max):
...    n, a, b = 0, 0, 1
...    while n < max:
...        yield b
...        a, b = b, a + b
...        n = n + 1
...    return 'done'

>>> f = fib(6)

>>> for n in fib(6):
...     print(n)

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break

5、迭代器

凡是可作用于for循环的对象都是可迭代对象,包括list,set等集合和生成器;
凡是可作用于next()函数的对象都是迭代器,它们表示一个惰性计算的序列,生成器都是迭代器;
集合数据类型如list、dict、str等是可迭代对象但不是迭代器,不过可以通过iter()函数获得一个迭代器对象。

例如:

if __name__ == "__main__":
    a = [1, 2, 3]
    b = iter(a)
    try:
        while True:
            print(next(b))
    except StopIteration as e:
        print(e.value)

>>> output:
1
2
3
None

扩展:
Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。这就是list,dict等集合跟生成器的本质区别

参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640

你可能感兴趣的:(python高级特性(生成器,迭代器区别))