#Python中迭代器

Python中迭代器

迭代是一个动词,它指的是一种操作,在Python中,就是 for 循环。
可迭代对象:可以直接作用于for循环的对象统称为可迭代对象(Iterable)
可以用isinstance()取判断一个对象是否是Iterable对象
可以直接作用于for的数据类型一般分两种
1,集合数据类型,如list,tuple,set,string
2,是generator,包括生成器和带yield的generator function(函数生成器)

特点:

a)访问者不需要关心迭代器内部的结构,仅需通过next()方法或不断去取下一个内容

b)不能随机访问集合中的某个值 ,只能从头到尾依次访问

c)访问到一半时不能往回退

d)便于循环比较大的数据集合,节省内存

e)也不能复制一个迭代器。如果要再次(或者同时)迭代同一个对象,只能去创建另一个迭代器对象

from  collections import Iterable  #导入包
from  collections import Iterator  #导入包

print(isinstance([],Iterable))						# True 是可迭代对象
print(isinstance((),Iterable))
print(isinstance({},Iterable))
print(isinstance("",Iterable))
print(isinstance(1,Iterable))						# False
print(isinstance((x for x in range(10)),Iterable))
#(输出)	True
		True
		True
		True
		False
		True

迭代器:
不但可以作用于for循环,换可以被next()函数不断调用并返回下一个值
,直到最后跑出一个StopIteration错误表示无法继续返回下一个值

可迭代对象:可以被next()函数调用并不断返回下一个值得对象称为迭代器(Iterator对象)
可以使用isinstance()函数判断一个对象是否是Iterator

from  collections import Iterator  #导入包

print(isinstance([],Iterator))
#(输出)False
print(isinstance((),Iterator))
#(输出)False
print(isinstance({},Iterator))
#(输出)False
print(isinstance("",Iterator))
#(输出)False
print(isinstance(1,Iterator))
#(输出)False
print(isinstance((x for x in range(10)),Iterator))
#(输出)True
#(只有最后一个True 因为只有最后一个才为迭代器)

l = (x for x in range(5))
print(next(l))
#(输出)0
print(next(l))
#(输出)1
print(next(l))
#(输出)2
print(next(l))
#(输出)3
print(next(l))
#(输出)4

#print(next(l))			  #超过数值报错

#转成迭代器 Iterator对象
a = iter([1,2,3,4,5])
print(next(a))
#(输出)1
print(next(a))
#(输出)2
print(next(a))
#(输出)3

print(isinstance(iter([]),Iterator))
#(输出)True
print(isinstance(iter(()),Iterator))
#(输出)True
print(isinstance(iter({}),Iterator))
#(输出)True
print(isinstance(iter(""),Iterator))
#(输出)True

迭代与按下标访问数组最大的不同是,后者是一种具体的迭代实现方式,而前者只关心迭代结果,根本不关心迭代内部是如何实现的。

dict的迭代器
把dict转换成一个包含所有value的list,我们迭代的就是 dict的每一个 value:

扫描二维码关注公众号,回复: 3471247 查看本文章
d = { 'A': 55, 'B':65, 'C': 79 }
print (d.values())
#(输出)dict_values([55, 65, 79])

for v in d.values():
    print (v)
#(输出)		55
			65
			79

一个 for 循环中,同时迭代 key和value:

d = { 'A': 55, 'B': 65, 'C': 79 }
print (d.items())
#(输出)dict_items([('A', 55), ('B', 65), ('C', 79)])

反向迭代reversed():
使用内置的reversed()函数

a = [1, 2, 3, 4]
for x in reversed(a):
    print(x) 
#(输出)	4 
		3 
		2 
		1

enumerate对象通过for循环迭代一次后就不能再被迭代:
这是因为enumerate是一个迭代器;
迭代器是一次性消耗品,当循环以后就空了。
不能再次使用;通过深拷贝可以解决;

e = enumerate([1,2,3])
for x,y in e:
    print(x,y)
#(输出)	0 1
		1 2
		2 3
for x,y in e:
    print(x,y)				#再次输入时,输出为空
#(输出)

深拷贝:

import copy
e = enumerate([1,2,3])
e_deepcopy = copy.deepcopy(e)
for x,y in e:
   print(x,y)
#(输出)	0 1
		1 2
		2 3
for x,y in e_deepcopy:
   print(x,y)
#(输出)	0 1
		1 2
		2 3

生成器(generator)
yield 的函数在 Python 中被称之为 generator(生成器)
Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。用生成器来实现斐波那契数列的例子是:
它特殊的地方在于函数体中没有return关键字,函数的返回值是一个生成器对象。当执行f=fib()返回的是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码。

import itertools
def fib():
    prev, curr = 0, 1
    while True:
        yield curr
        prev, curr = curr, curr + prev

f = fib()
print(list(itertools.islice(f, 0, 10)))
#(输出)[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

相比其它容器对象它更能节省内存和CPU,当然它可以用更少的代码来实现相似的功能。

def something():
    result = []
    for ... in ...:
        result.append(x)
    return result

#转换为:

def iter_something():
    for ... in ...:
        yield x

猜你喜欢

转载自blog.csdn.net/weixin_43097301/article/details/82950575