迭代器(Iterator)和生成器(Generator)的区别是什么?
生成器是迭代器,但并非所有迭代器都是生成器。
迭代器通常是具有next方法以从流中获取下一个元素的对象。生成器是与函数相关联的迭代器。
例如在Python中的生成器:
def genCountingNumbers():
n = 0
while True:
yield n
n = n + 1
这样做的好处是您无需将无限数量的数值存储在内存中以便迭代。
您可以像使用任何迭代器一样使用它:
for i in genCountingNumbers():
print i
if i > 20: break # Avoid infinite loop
您还可以遍历数组:
for i in ['a', 'b', 'c']:
print i
这里有太多的Python,太多人说生成器是实现无限迭代器的唯一方法。这是我提到的例子(所有自然数的平方)在C#中的实现。 ExplicitSquares 显式地实现了一个迭代器(在C#中称为 IEnumerator)。 ImplicitSquares 使用生成器完成相同的操作。两者都是无限迭代器,并没有后台集合。 唯一的区别是状态机是否被明确说明,或者使用生成器。
using System.Collections;
using System.Collections.Generic;
using System;
class ExplicitSquares : IEnumerable<int>
{
private class ExplicitSquaresEnumerator : IEnumerator<int>
{
private int counter = 0;
public void Reset()
{
counter = 0;
}
public int Current { get { return counter * counter; }}
public bool MoveNext()
{
counter++;
return true;
}
object IEnumerator.Current { get { return Current; } }
public void Dispose(){}
}
public IEnumerator<int> GetEnumerator()
{
return new ExplicitSquaresEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class ImplicitSquares : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
int counter = 1;
while(true)
{
int square = counter * counter;
yield return square;
counter++;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class AllSquares
{
private static readonly int MAX = 10;
public static void Main()
{
int i = 0;
foreach(int square in new ExplicitSquares())
{
i++;
if(i >= MAX)
break;
Console.WriteLine(square);
}
Console.WriteLine();
int j = 0;
foreach(int square in new ImplicitSquares())
{
j++;
if(j >= MAX)
break;
Console.WriteLine(square);
}
}
}
生成器是迭代器的一种实现。它通常是一个例程,向其调用者产生多个值,而不仅仅是一个。
在C#中
// yield-example.cs
using System;
using System.Collections;
public class List
{
public static IEnumerable Power(int number, int exponent)
{
int counter = 0;
int result = 1;
while (counter++ < exponent)
{
result = result * number;
yield return result;
}
}
static void Main()
{
// Display powers of 2 up to the exponent 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
}
def integers():
int n = 0
while True:
yield n
n += 1
yield n
语句。函数将返回该值,并在下一次调用时从该点继续执行。(来自javascript使用者,但与其他人一样)
迭代器是一个具有.next()函数的对象
生成器是一个函数,一旦调用,就会产生一个迭代器,它是一个迭代器的工厂。
在JavaScript中,生成器函数需要特殊的语法function*(){}和使用yield关键字。
请参阅MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
def factors(n):
for i in xrange(1, n+1):
if n % i == 0:
yield i
for n in factors(1234567890):
print n
易于理解的定义如下:
迭代器是用于迭代一系列项目的对象。
生成器是生成迭代器的函数。
生成器迭代器是由生成器生成的迭代器。
流行但令人困惑的定义如下:
迭代器是一个遍历项目列表的对象。
生成器函数是一个生成迭代器的函数。
生成器是由生成器函数生成的迭代器。
迭代器通常用于遍历一组项目。通常具有MoveNext()和Current()方法。 MoveNext()将把指针移动到下一个集合项(如果可能),并根据成功与否返回true/false。 Current()将提供实际值。
生成器是迭代器的一种实现,但它不是指向预先存在的集合,而是在每个MoveNext()调用上创建新项。