如果给定一个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
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
Python的for
循环本质上就是通过不断调用next()
函数实现的