在数据科学和Python面试中,经常会遇到一些中级话题。本系列文章旨在帮助有志于在Python领域更进一步的读者,深入理解这些话题。今天,将继续探讨Python中的迭代器和生成器。
“迭代”在计算机编程中的意思是“重复执行任务”。根据Wikipedia的定义,迭代器是一个允许程序员遍历容器(特别是列表)的对象。这意味着迭代器与遍历元素有关。
那么,什么是“可迭代”的呢?简单来说,就是可以循环遍历的对象。例如,列表就是一个可迭代对象,因为可以通过循环遍历它的元素。
让通过一个简单的例子来理解这个概念。首先,创建一个列表,然后尝试使用Python内置的iter()
方法将其转换为迭代器。
my_list = [1,2,3,5,8,13]
final_list = iter(my_list)
输出结果将类似于这样。接下来,尝试对final_list
使用next()
函数。
next(final_list)
输出结果将是列表中的第一个元素。再次使用next()
函数,将得到列表中的第二个元素,以此类推。
通过这个例子,可以明白iter()
方法将一个可迭代对象(如列表)转换为迭代器。总结来说,可迭代对象可以被转换为迭代器,而迭代器是一个具有next()
方法的对象。
Wikipedia将生成器定义为一种特殊的协程,称为生成器。与子程序相比,生成器协程可以多次向其调用者yield
值,而不是只返回一次。
现在,将注意力转向生成器。Python中的生成器是一种创建迭代器的简便方法。它是一个函数,返回一个可以迭代的对象(一次一个值)。让通过一个没有使用生成器的简单例子,然后尝试使用生成器来实现相同的操作。希望创建一个函数,将列表中的所有元素平方。
def square(my_list):
result = []
for i in my_list:
result.append(i**2)
return result
现在,让传入一个列表并查看结果。
final = square([1,2,3,4,5])
输出结果将是列表中每个元素的平方。这个过程非常直接。实现了一个函数,初始化了一个名为“result”的空列表,然后循环遍历想要传入的“my_list”,并将平方结果逐个追加到“result”列表中。此外,这个过程是一次性计算所有结果的,这意味着它消耗更多的内存,从性能角度来看,这个过程可能效率不高。
如果尝试使用生成器来实现相同的操作呢?
def square(my_list):
for i in my_list:
yield i**2
让传入一个列表:
final = square([1,2,3,4,5])
输出结果将是一个生成器对象,因此可以对final
变量使用next()
函数。让试试:
next(final)
输出结果将是列表中第一个元素的平方。再次使用next()
函数,将得到列表中第二个元素的平方,以此类推。
在这里做了什么不同的事情?在第二个例子中,像以前一样创建了一个函数。然后,没有初始化一个空列表,而是直接循环遍历要传入的列表。在每次循环中,yield
相应的平方值,仅此而已!最后,创建了一个“final”变量来传入想要的列表。这是生成器。当应用next()
方法时,每次都获得了平方值。这意味着,不是所有结果都是一次性计算的。这在Python中被称为惰性求值。简而言之,惰性求值是一个过程,其中对象在需要时才被评估,而不是在创建时。
yield
的作用是什么?yield
简单地产生一系列值。通常在想要迭代一个序列时使用yield
,但yield
方法的想法是不在内存中存储整个序列,而是在被告知时才执行。请注意,可以在函数中拥有多个yield
语句,但不能拥有多个返回。
大家好!叫Akash,已经作为Python开发者工作了4年多。在职业生涯中,最初是尼泊尔最大求职网站Merojob的初级Python开发者。后来,参与了尼泊尔第一家拼车公司Tootle的数据科学和研究工作。目前,一直在积极参与数据科学以及使用Django的Web开发。
可以在以下链接找到其他项目:
在LinkedIn上联系:
电子邮件: |