TA的每日心情 | 开心 2019-11-20 15:00 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完全理解 Python 迭代对象、迭代器、生成器之可迭代对象+ X& i8 P& X) X' z
可迭代对象(iterable): ]. t( z4 n# ^& n7 l5 Z/ D0 _
很多容器都是可迭代对象,此外还有更多的对象同样也是可迭代对象,比如处于打开状态的files,sockets等等。但凡是可以返回一个迭代器的对象都可称之为可迭代对象
' l* z: A: V3 Y3 J# I/ Z>>> x = [1, 2, 3]: s+ U' w5 i* v% F$ E
>>> y = iter(x)- {# ?/ m T" E0 q4 D# z3 m7 g: Z5 r
>>> z = iter(x)
5 X, l6 i4 R' e- ]; m5 ]>>> next(y)
; W$ _ {1 W' p5 |$ U+ ~+ g1
. H0 q. a5 K( T) f( {>>> next(y)! W8 f' g1 y O7 f
2
+ l; {* b6 u6 [) c>>> next(z)5 B' I+ X4 o7 N( T% V0 P7 Y! T2 |
18 x6 v$ Y! q2 H' a
>>> type(x)
: J' J" @( M: @3 f" x; \4 K, z8 _' U) a* G0 C: V) n) X [
>>> type(y)
6 n, Y; n: d/ l, S2 ], n- ?" k" N8 _' F: S, q
这里x是一个可迭代对象,可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型,list是可迭代对象,dict是可迭代对象,set也是可迭代对象。y和z是两个独立的迭代器,迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。9 _. i& V- r8 ^ n2 O
4 x' j' h' @9 K( t3 i0 Y) S: V
当运行代码:
2 p0 [- D J+ V; V" {3 c& h Dx = [1, 2, 3], ~+ Q" C# @$ r4 u6 ]/ x' m/ Q, a
for elem in x:7 g" L _3 k1 O$ x+ V7 i
...- K: A" L; [" x1 A
反编译该段代码,你可以看到解释器显示地调用GET_ITER指令,相当于调用iter(x),FOR_ITER指令就是调用next()方法,不断地获取迭代器中的下一个元素,但是你没法直接从指令中看出来,因为他被解释器优化过了。
3 L2 Q1 k& N% |/ G0 H$ r7 J" p4 R>>> import dis
2 J: w7 I0 }' L m q4 q7 F0 y>>> x = [1, 2, 3]2 g5 u- Z8 E$ Z( ?
>>> dis.dis('for _ in x: pass')+ N1 F& [& U9 Z. ]7 L
1 0 SETUP_LOOP 14 (to 17)1 Y7 c7 P, _, b, }# D U4 q
3 LOAD_NAME 0 (x)! B# G |2 R8 y: i; d
6 GET_ITER
) h) @5 ~/ u3 m4 B>> 7 FOR_ITER 6 (to 16)7 R6 \3 s/ |! K
10 STORE_NAME 1 (_)) J M- `7 W) M/ O/ j; ^8 j
13 JUMP_ABSOLUTE 7
' h0 N7 b5 U1 D2 g0 K1 F>> 16 POP_BLOCK) N! D7 o' |0 ]. ?6 V2 z) `: w* b
>> 17 LOAD_CONST 0 (None)3 F+ g5 J& `9 {5 j& U* Q
20 RETURN_VALUE |
/ B% j$ n i4 ?0 r! K: U# t3 l8 b- f- B' n
# C' H; o t8 w/ |, H# A& u
# Y! C9 L, ?; Y. q6 e" N7 f
6 C1 Y" y8 L. c* o- i
1 s! E. D9 c5 j# D" E& i+ ] |
. Y1 p0 d( A1 o& E. h8 s |
8 @) s% U' X9 W' X! j7 u' x |
|