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

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    完全理解 Python 迭代对象、迭代器、生成器之可迭代器  r+ x" I3 I+ Z7 q; l2 q2 C' L
    迭代器(iterator)
    , K, U/ g* w: S0 |: g$ h# E# d" ^6 g
    那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。0 ]) j: o! X' Y) o1 B2 {4 E
    0 t6 Y5 E  C6 \+ K6 R. J
    所以,迭代器就是实现了工厂模式的对象,它在你每次你询问要下一个值的时候给你返回。有很多关于迭代器的例子,比如itertools函数返回的都是迭代器对象。- y; C/ `4 n/ t

    9 T/ B/ ~9 K2 D) @生成无限序列:1 b- L) q" J( G8 p, n
    >>> from itertools import count
    $ ~* {; G/ y% ~2 z4 X3 g. h>>> counter = count(start=13)+ H8 f* D( k' |  U9 T$ N0 v, _
    >>> next(counter)4 A' }/ Y! y5 O* \" C
    13) r0 q; D  A+ y3 c9 T" T8 ^7 x6 u
    >>> next(counter)( A; w, |' [8 K6 t, Y+ B# m
    14; d! I" j3 R% Z8 @( P! x8 T5 }

    ; @0 \0 Y% s/ b8 O8 a( U从一个有限序列中生成无限序列:7 ]1 z& C6 M  Q) ^, I7 u* H
      _$ b% F0 X% w) W! Q: I+ J
    >>> from itertools import cycle
    & X$ p" V( R: ]7 C8 l>>> colors = cycle(['red', 'white', 'blue'])
    / m! D  O9 a! d1 L: Q' Z>>> next(colors)
    - R+ s8 [- S0 g# p'red'
    + ?( a2 i1 X( `2 f>>> next(colors)
    - M& n# c; }3 X. _: A'white'# Z2 o* P6 D1 B3 S8 o
    >>> next(colors)0 U. `% Y6 Z0 J' [# D' D3 }
    'blue'
    , @$ y- l- o2 r5 [+ ~>>> next(colors)
    & P# d2 d9 t  o. d1 y2 V( y, \9 x'red'
    # E% o0 y! j, i- p: ~3 `7 B. p% n: {) H- e( T
    从无限的序列中生成有限序列:
    5 i5 o/ y2 I& ^* @1 ]6 z>>> from itertools import islice
    # C- Y" J4 P0 s) j' i. O>>> colors = cycle(['red', 'white', 'blue']) # infinite
    0 ?" h* ^  _# @: b. t6 K3 i0 W>>> limited = islice(colors, 0, 4) # finite% N  I  l9 R: A! e# Y7 b( f0 j
    >>> for x in limited:6 d; f; w; f0 O0 b* L
    ... print(x)8 s6 P# l8 s# k$ K2 V
    red/ a- S' ?# b( B9 I; X+ W
    white
    9 R1 n3 M* S2 P5 Cblue4 T5 e1 d7 z8 T' W. u
    red
    ' e8 Q, e; ~; H9 K, x4 h$ E6 p
    5 I& W$ D0 m3 |5 w为了更直观地感受迭代器内部的执行过程,我们自定义一个迭代器,以斐波那契数列为例:
    1 Z) p( S2 o5 B1 R% |class Fib:
    ! x0 O1 R, s% }6 ]+ C2 D* Mdef __init__(self):, W6 [. ]& R1 W! V- w3 b. m
    self.prev = 00 Y$ ~+ f# d/ \$ k0 x
    self.curr = 10 ^  \# [# t8 s6 N; R
    9 x7 M7 L2 A0 _7 U# l( H0 D* D
    def __iter__(self):
    % l- K6 ~, j1 O; Creturn self
    4 {) _8 _9 ]- z& t/ i" y- l# J$ f5 T( \
    def __next__(self):
    7 c  @: T7 S* ]1 e6 Rvalue = self.curr
    0 h$ q8 H5 s7 K8 J0 d: Xself.curr += self.prev9 \! Y) {3 r# ]+ [
    self.prev = value% I6 N' d7 N6 ]% w
    return value8 V) w1 c: b1 x' A
    & q# ?4 @% f5 k+ R0 O; A1 M
    >>> f = Fib(); g' `7 }$ v2 M  V" @( z5 T
    >>> list(islice(f, 0, 10))
    + c6 p. l6 d9 r[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; c" D8 [+ P! L- B8 ^
    8 v+ I: J! w; c& j3 C. g
    Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量prev和curr用户维护迭代器内部的状态。每次调用next()方法的时候做两件事:
    - e! b: V4 U% P- K# M0 s4 K0 m$ \0 b5 l: ~8 {) w1 r3 k) W
    为下一次调用next()方法修改状态* c1 X3 f+ {1 a) R6 m0 T
    为当前这次调用生成返回结果  u" X: S! G" g+ l* R/ y7 {
    , x5 q9 R) [0 H8 J  Y( A
    迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

    ! I! a' D5 e* N$ K
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-23 09:21 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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