当python解析for x in foo循环规则时,实际会调用iter(foo)方法,也就是foo中的迭代器(__iter__)方法。每当循环一次就会调用next方法,直至元素遍历完成。迭代器是包含状态的,不能反复使用。比如如下代码:
import random
def l ():
"""
测试链表迭代器
"""
l =[random.randint(1,100000) for x in range(10)]
for _,v in enumerate(l):
yield v
def test_sum(it):
sum = 0
for value in it:
sum = sum + value
return sum
当以如下方式调用代码时,会发现第二次调用无结果:
it = l()
print(test_sum(it))
print(test_sum(it))
以C#为例,迭代器在编译器内部会将迭代器生成一个类,方法l会返回一个对象:
.method private hidebysig instance class[mscorlib]System.Collections.Generic.IEnumerator`1
l() cil managed
{
//代码大小20 (0x14)
.maxstack 2
.locals init ([0] class TestRef.A/'d__0' V_0,
[1] class[mscorlib]System.Collections.Generic.IEnumerator`1 V_1)
IL_0000: ldc.i4.0
IL_0001: newobj instance void TestRef.A/'d__0'::.ctor(int32)
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldarg.0
IL_0009: stfld class TestRef.ATestRef.A/'d__0'::'4__this'
IL_000e: ldloc.0
IL_000f: stloc.1
IL_0010: br.s IL_0012
IL_0012: ldloc.1
IL_0013: ret
}// end of method A::l
而该对象实现了系统的标准方法,每次返回对象后重置状态,定义如下:
迭代器返回的是一个对象,而List返回的是一个列表,在处理大量记录时,尽量使用迭代器传参数避免使用列表消耗大量内存。
领取专属 10元无门槛券
私享最新 技术干货