在Python中,迭代器(Iterator)是一种对象,它表示一个数据流,允许你按顺序逐个访问数据元素,而无需一次性将所有数据加载到内存中。
迭代器的工作原理
迭代器通过实现两个特殊方法__iter__()
和__next__()
来工作。
-
__iter__()
:返回一个迭代器对象本身。 -
__next__()
:返回流中的下一个元素。如果流中没有更多元素,则引发StopIteration异常。
任何实现了这两个方法的对象都可以被称为迭代器。此外,迭代器还遵循迭代器协议,这意味着它们可以与Python中的循环结构(如for循环)无缝协作。
自定义迭代器
以下是一个简单的迭代器示例,它生成从0到9的数字:
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
num = self.current
self.current += 1
return num
else:
raise StopIteration
for n in MyRange(0, 5):
print(n)
运行结果如下:
0
1
2
3
4
在这个例子中,MyRange类是一个迭代器,它生成从start到end-1
的数字。
转换为迭代器
你可以使用内置的iter()函数将任何可迭代对象(如列表、元组等)转换为迭代器。
my_list = [1, 2, 3, 4]
list_iter = iter(my_list)
print(type(list_iter)) # <class 'list_iterator'>
print(next(list_iter)) # 1
使用内置迭代器
Python中有许多内置的数据结构(如列表、元组、集合、字典等)和生成器,它们都支持迭代协议,可以直接用于for循环中。
# 列表迭代器
my_list = [1, 2, 3, 4, 5]
my_list_iterator = iter(my_list)
print(next(my_list_iterator)) # 输出: 1
print(next(my_list_iterator)) # 输出: 2
# 字符串迭代器
my_str = "hello"
my_str_iterator = iter(my_str)
print(next(my_str_iterator)) # 输出: h
print(next(my_str_iterator)) # 输出: e
# 字典迭代器(遍历键)
my_dict = {'a': 1, 'b': 2, 'c': 3}
my_dict_iterator = iter(my_dict)
print(next(my_dict_iterator)) # 输出字典的一个键,例如: 'a'(具体输出取决于字典的内部结构)
# 使用for循环遍历迭代器
for item in my_list:
print(item) # 输出: 1, 2, 3, 4, 5
需要注意的是,虽然上述示例中我们显式地创建了迭代器并使用next()方法进行了迭代,但在实际编程中,更常见的是直接使用for循环来遍历可迭代对象,因为for循环提供了更简洁、更直观的语法。
无限迭代器
你还可以创建无限迭代器,只要__next__
方法不引发StopIteration异常即可。
例如,一个简单的无限迭代器可以生成无限的自然数序列:
class InfiniteSequence:
def __init__(self, start=0):
self.number = start
def __iter__(self):
return self
def __next__(self):
num = self.number
self.number += 1
return num
使用无限迭代器(注意:这将会无限循环,需要手动中断)
for number in InfiniteSequence():
print(number)
if number >= 10: # 示例:打印前10个自然数
break
生成器
在Python中,生成器(Generators)是一种特殊的迭代器,用于生成一系列的值,而不需要一次性将它们全部加载到内存中。生成器通过函数创建,并使用yield关键字逐个返回值。这使得生成器在处理大量数据时非常高效,因为它们可以按需生成值,而不是一次性生成整个序列。
当在生成器函数中使用yield语句时,函数的执行将会暂停,并将yield后面的表达式作为当前迭代的值返回。
然后,每次调用生成器的next()方法或使用for循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到yield语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。
调用一个生成器函数,返回的是一个迭代器对象。
下面是一个简单的示例,展示了生成器函数的使用:
def simple_generator():
yield 1
yield 2
yield 3
# 使用生成器
gen = simple_generator()
print(next(gen)) # 输出: 1
print(next(gen)) # 输出: 2
print(next(gen)) # 输出: 3
print(next(gen)) # 抛出 StopIteration 异常
生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。
以下实例使用yield实现斐波那契数列:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 使用生成器,限制输出前10个值
fib_gen = fibonacci()
for _ in range(10):
print(next(fib_gen))