在Python编程语言中,因其灵活性和强大的功能而广受欢迎。在处理Python时,经常会遇到一些功能,它们在简化复杂性方面的使用与其知名度并不相称。这些隐藏的特性在很多人中并不广为人知,但在数据分析和数据科学领域却非常有用。Python中的迭代器和可迭代对象就属于这一类。它们的重要性不言而喻!
在软件开发中,一个核心原则是“不要重复自己”(DRY原则),这一原则在《实用程序员》一书中被阐述为:“系统中的每项知识都必须有一个单一的、明确的、权威的表示。”在现代编程中,这一原则的一个具体应用是通过迭代来遍历一系列项目,并对它们执行定义的操作。迭代最基本的形式是for循环。虽然许多其他语言如Swift和JavaScript使用三表达式for循环,但Python使用更简洁的for循环语法。
要理解迭代的确切含义,需要了解以下几点:迭代在通俗语言中意味着“重复步骤”。在编程中,迭代被定义为重复执行指定次数的代码块。为了实现迭代,可以使用for循环等循环结构。
可迭代对象是可以迭代的对象。要理解可迭代对象的确切含义,需要了解以下几点:可迭代对象是可以被循环遍历的对象。像列表、元组、集合、字典、字符串等对象被称为可迭代对象。简而言之,可迭代对象就是可以在for循环中遍历的任何对象。
更简单地说,可迭代对象是一个包含数据或值的容器,通过迭代它来逐个获取元素(可以逐个遍历所有给定的值)。可迭代对象有一个内置的双下划线方法__iter__。如何检查一个对象是否是可迭代的?如果一个对象可以从中获取迭代器,那么它就被称为可迭代的。一个更简单的方法是检查它是否支持__iter__。怎么做呢?这里使用dir()函数,它返回对象支持的属性和方法列表,通过查看所有属性和方法,可以找到所有并从中选择所需的方法。
在可迭代对象上调用iter()函数会给一个迭代器。在迭代器上调用next()函数会给下一个元素。如果迭代器已经耗尽(如果没有更多的元素),调用next()会引发StopIteration异常。
# 字符串作为可迭代对象
for i in 'chirag':
print(i)
print('-----')
# 列表作为可迭代对象
for i in [1, 2, 3]:
print(str(i*2))
迭代器是一个代表数据流的对象,它使用__next__()方法一次产生一个数据值。要理解迭代器的确切含义,需要了解以下几点:在Python中,迭代器是一个实现了迭代器协议的对象,这意味着它包含__iter__()和__next__()等方法。迭代器是一个有状态的可迭代对象,因此它在迭代过程中记住了自己的位置。
例如,生成器是一种迭代器,它们一次返回一个元素的数据。它执行迭代以逐个访问可迭代对象的元素。由于它维护了元素的内部状态,迭代器知道如何获取下一个值。迭代器支持哪些内置方法?迭代器支持内置的双下划线方法__iter__()和__next__()。迭代器只能使用__next__()向前移动。但请记住,迭代器不能向后移动或重置。
要了解更多关于Python中双下划线方法的信息,请参阅相关链接。让更深入地了解__next__()函数:__next__()方法不接受任何参数,并且总是返回流的下一个元素。如果流中没有更多元素,__next__()必须引发StopIteration异常。迭代器不必是有限的。编写一个产生无限数据流的迭代器是完全合理的。
# 创建一个迭代器
number_iterator = iter([1, 2, 3, 4, 5])
print(type(number_iterator))
print(next(number_iterator))
print(next(number_iterator))
print(next(number_iterator))
print(next(number_iterator))
print(next(number_iterator))
# 迭代器耗尽后,next()函数引发StopIteration。
print(next(number_iterator))
在现代,手中有大量的数据,处理这些庞大的数据量为那些想要对这些数据进行某种分析的人创造了问题。因此,如果曾经因为处理大量数据而挣扎,并且机器耗尽了内存,那么会爱上Python中的迭代器概念。
因此,与其一次性将所有数据放入内存,不如分批处理,只处理当时所需的数据,这样岂不是更好?结果,这将极大地减轻计算机内存的负担。这正是迭代器所做的!因此,可以使用迭代器节省大量内存,因为迭代器在生成时不计算它们的项,只有在需要时才计算。
首先,需要指出的是“迭代器是可迭代的”,如果在for循环中使用迭代器,它仍然可以工作。然而,相反的情况并不总是正确的。例如,像字符串和列表这样的可迭代对象并不是迭代器,它们没有next()方法。
给定上述迭代器和可迭代对象之间的差异,它们在for循环中的使用是不同的。现在,如下面的示例所示,可以使用相同的可迭代对象(即列表)在两个for循环中,而不会发生任何错误。相比之下,迭代器只能使用一次,因为完成第一个for循环后,迭代器已经遍历了所有元素,以至于没有更多的元素可以迭代。
# 多次使用可迭代对象在for循环中
number_iterable = [1, 2, 3]
for i in number_iterable:
print(i)
print('-----')
for i in number_iterable:
print(i)
print('-----')
# 多次使用迭代器在for循环中
number_iterator = iter([1, 2, 3])
for i in number_iterator:
print(i)
print('-----')
for i in number_iterator:
print(i) # 什么也不打印
在本节中,将讨论可迭代对象和迭代器之间的区别:
让通过以下示例来理解上述各点:
# 1. 可迭代对象和迭代器都可以使用for循环迭代。
list_1 = [1,2,3,4,5]
list_2 = iter(list_1)
print(list_2)
# 通过for循环迭代可迭代对象(list_1)。
for element in list_1:
print(element, end=" ")
print()
# 通过for循环迭代迭代器(list_2)。
for element in list_2:
print(element, end=" ")
# 输出:
# 1 2 3 4 5
# 1 2 3 4 5
list_1 = [1,2,3,4,5]
# 返回一个迭代器
list_2 = iter(list_1)
print(list_2)
# 在迭代器本身上调用iter()函数。
list_3 = iter(list_2)
print(list_3)
print(list_2 == list_3)
# 输出:True