找回密码
 注册
关于网站域名变更的通知
查看: 240|回复: 1
打印 上一主题 下一主题

完全理解 Python 迭代对象、迭代器、生成器之可迭代器

[复制链接]
  • TA的每日心情
    开心
    2019-11-20 15:00
  • 签到天数: 2 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2018-11-13 09:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    完全理解 Python 迭代对象、迭代器、生成器之可迭代器
    7 T- P" K! M- }. q
    迭代器(iterator)
    6 h- s- w) ~& L9 P, O% {9 F9 Q% l8 p6 x5 n4 X
    那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。" t6 P' E0 A4 [, {- G
    ; ~4 d! }6 r/ l, {3 f
    所以,迭代器就是实现了工厂模式的对象,它在你每次你询问要下一个值的时候给你返回。有很多关于迭代器的例子,比如itertools函数返回的都是迭代器对象。. i: y8 W' E7 [; O6 F: C

    # t0 a& x0 U2 ]: a" i, }" x生成无限序列:$ p, A& e: `% }4 I+ F" q  h
    >>> from itertools import count
    ) a9 X( Y( C9 S1 \>>> counter = count(start=13)
    6 S! M& z1 S4 C2 S4 P>>> next(counter)
    / y2 L% A* i( z8 b& v, C+ c* z13
    1 P5 ~) r) ~6 n>>> next(counter)& c! Z) e, m1 b' F& W- [, t
    14
    ; {) u3 J6 r: L- _; J/ P7 D" O& ~- Z6 {+ o0 ^2 |! R9 u
    从一个有限序列中生成无限序列:
    " e$ I# P: ~* j- E4 t" _; G  {
    >>> from itertools import cycle
    $ @. J& m- H4 N3 Q>>> colors = cycle(['red', 'white', 'blue'])
    - X% }& Z& k3 t, Z>>> next(colors)
    8 Z/ P2 H: q3 S' R: z8 _'red'# h4 a" ~2 h! L9 A! l8 X4 e
    >>> next(colors): `. Z" O( l% Z  Y3 u5 U5 l8 F
    'white'
    ' x% Z9 S: x: q/ l+ Q, }>>> next(colors)
    8 H- @3 X# h! {'blue'
    * S: E+ m, n9 A! q3 y4 B  g>>> next(colors)
    ' F$ v! h! X0 w2 P'red'' r7 E4 T: n4 h7 t& k& \
    / l5 O  u( g1 T
    从无限的序列中生成有限序列:
    ( q$ j% j+ s. S+ C9 m0 p8 m% \>>> from itertools import islice6 K: X1 [! N1 Z6 }' |3 D
    >>> colors = cycle(['red', 'white', 'blue']) # infinite! j% }$ j0 b# Q/ Q( A* V  Q/ J( y
    >>> limited = islice(colors, 0, 4) # finite& Q, a- v7 R* f2 `9 h
    >>> for x in limited:$ e' I1 W5 `% `: p; ~% W$ v1 o* W% T8 @
    ... print(x)% d* [+ I) x5 \; _; W% V! E1 T+ p# r
    red
    7 D* p. b! {( hwhite
    1 [  T: M9 |& r5 C$ o( Y8 \blue" W6 Q; U3 g) ?- P7 _
    red/ G( l; F5 L" ^  K: {1 q
      g3 }5 l8 G6 }$ S4 x
    为了更直观地感受迭代器内部的执行过程,我们自定义一个迭代器,以斐波那契数列为例:8 a5 l$ n$ `, T8 A+ U' ~& h
    class Fib:
    ( n; k6 R# b# O3 z" u6 Z, Pdef __init__(self):  {" K" n$ h! q0 K+ b
    self.prev = 0# ~; @' ~$ K) B- |
    self.curr = 1
      l  D) B, d9 z- b/ H5 S4 \+ K) [& I! o; {  W/ `+ h6 D+ O
    def __iter__(self):
    7 C: D) i" M; wreturn self3 e! }+ t" G, V
    7 v8 B/ y& f1 J: q5 ]+ L3 S
    def __next__(self):) _/ Y9 {$ l- I# h" I3 i; f
    value = self.curr/ N) m3 R; v3 Z% c" \% i8 Y6 t/ S4 P
    self.curr += self.prev1 J" e" D$ t; A' O* d
    self.prev = value
    ( u0 T. X5 A5 c6 k  y( Yreturn value% _8 u" r& d+ E( |
    + W. C3 C2 L' D  H" m! b
    >>> f = Fib()
    # q, I6 s# j& R# r7 S) ]>>> list(islice(f, 0, 10))
    : r2 |! i) b, A* O# Y[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
    5 g: _( g0 d) q! `+ Q! s0 O: W
    ' B: q' w4 k5 `9 P9 FFib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量prev和curr用户维护迭代器内部的状态。每次调用next()方法的时候做两件事:, g/ }# p3 H  m; P$ Y

    6 b, W4 j4 G+ l, l! ?为下一次调用next()方法修改状态. g3 L, n* m" b! \1 B" }- O
    为当前这次调用生成返回结果$ r# h; l) f1 v* d, l  J
    " m2 f* s2 W" O6 h: Q
    迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

    5 M) J" P& q4 d
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-10-6 12:55 , Processed in 0.140625 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表