python中的迭代器

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
...     print(key)
...
a
c
b

当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。

那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C
可迭代对象有list tuple dict str set


# a = [x*x for x in range(10)]#列表生成式
#
# print(a)

def f(n):
return n**3

a=[f(x) for x in range(10) ]
print(a)
print(type(a))
列表生成式的类型为list
or循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>> a = [x * x for x in range(1, 11) if x % 2 == 0]
print(a) [4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

>>> a = [m + n for m in 'ABC' for n in 'XYZ']
print(a) ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']


通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个很多元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

# s = (x**2 for x in range(10))
# print(s)
#
# #print(s.__next__()) #内部方法
# print(next(s))#等价于s.__next__() in py2:s.next()
# print(next(s))#等价于s.__next__() in py2:s.next()
# print(next(s))#等价于s.__next__() in py2:s.next()
# for i in s:#生成器是一个可迭代对象(Iterable)
# print(i)#占用内存小,迭代时使用完了直接回收
# #生成器一共有两种创建方式:
# #1:(x*x for x in range(x))
# #2:yield()
def bar():
print('ok1')
count = yield 1
print(count)
yield 2

b = bar()
# next(b)
s = b.send(None)# next(b) 第一次send 前如果没有next,只能传一个sned(none)
print(s)
b.send('fff')
》》》ok1
》》》1
》》》fff

如果要获得return值则需要使用except:
>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

凡是可作用于for循环的对象都是Iterable类型;


凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;


集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。


Python的for循环本质上就是通过不断调用next()函数实现的

 





原文地址:https://www.cnblogs.com/MY0213/p/7767284.html