在python中一切皆为对象,对于迭代对象本身,可以定义出专门的对象,即迭代器
对于列表、元组、字典等类型的数据对象,我们可以使用for循环语句从其中依次取出数据进行使用,这一过程称为遍历,也叫迭代。我们可以把这类数据对象称为可迭代对象
可迭代对象内部通过一个内置的__iter__方法来构成,其作用是返回一个迭代器对象1
对于列表元组等可迭代对象,可以使用iter()函数(实际上是调用了可迭代对象的__iter__方法)来获取这些可迭代对象的迭代器,然后调用next()函数(实际上是调用了可迭代对象的__next__方法)返回其中的下一个值
我们可以说,任何一个实现了_iter_和_next_方法的对象都是迭代器,r如果迭代器中没有元素则抛出StopIteration异常
class Fibonacci: def __init__(self): self.a=0 self.b=1 def __next__(self): result=self.a self.a,self.b=self.b,self.a+self.b if result>500:raise StopIteration return result def __iter__(self): return self fib=Fibonacci() # 实例化一个 for i in fib: print(i,end=',')
运行结果
上面的程序的__next__方法中尽管我们设置了一个StopIteration异常,但是实际运行中并没有在程序中抛出,这是因为这个异常在迭代中由系统处理了,所以想要将无限迭代改为有限迭代,可以在适当的位置抛出StopIteration异常
迭代器和生成器都只能一个值一个值产生,每迭代一次就得到一个值。迭代器需要在类中定义__iter__和__next__方法,使用时需要创建迭代器实例,生成器通过一个函数实现,可以直接调用,某种意义上来说,生成器的使用更加简洁
首先需要定义一个函数,在该函数中对某个集合或迭代器进行迭代,然后使用yield语句产生当前要生成的值,此时函数会被中止执行,直到下一次调用生成器代码迭代下一个值
def mygenerator(): nums=[1,2,3,4,5,6] for i in nums: yield i # 中止当前函数,提交当前要生成的值 for num in mygenerator(): # 对生成器进行迭代 print(num,end=',')
运行结果
利用一段特定形式的表达式从一个已知序列的元素得到另外一个序列的元素,这种用于序列推导的表达式称为推导式,利用推导式可以构建列表、字典和集合,但不可构建元组因为元组是不可变的数据类型,因此没有单独的元组推导式2,一般格式:【含有变量x的表达式 含有变量x的for循环 [含有变量x的条件表达式]】
返回结果为一个列表
字典推到是利用大括号将推导式括起来,一般形式:{f(x):g(x) 含有x的for循环 [含有变量x的条件表达式]
}
集合推导式符合推导式的一般形式,外面使用大括号括起来
将推导式的方法应用于生成器就是生成器表达式,需要将中括号改为小括号,返回结果是一个生成器表达式
使用生成器表达式几乎不消耗和使用内存,生成器使用惰性计算方式,只有在访问 的时候才取值,属于一种计算优化的方式。但由于生成器本身也是迭代器,遍历一次就因抛出StopIteration异常而无法继续遍历
python中定义了若干内置的可迭代对象,具有良好的稳定性和实用价值,如经常使用的range()函数,可以直接在内存中产生指定范围的数字序列
来源于map()函数的返回值,根据提供的函数对指定序列做映射,并形成映射数据构成的可迭代对象(map对象)。
语法格式:map(function,*iterable)
使用filter()函数可以返回一个filter过滤迭代器,目的是用于过滤序列中不符合条件的元素
语法格式:filter(function,iterable)
zip()函数的主要作用是将多个可迭代对象中的对应元素逐一组合形成zip对象构成新的迭代器,每个组合都是以元组的形式保存,最终多个元组形成一个新的序列和可迭代对象
enumerate()函数可以对迭代对象进行枚举,形成枚举迭代器
语法格式:enumerate(sequence[,start=0])
,start表示开始的索引
是要判断一个对象是否可迭代,可以使用isinstance()来判断 ↩︎
不可以使用推导式生成一个元组,但是可以使用tuple()函数将一个生成器表达式转换为元组 ↩︎