1、迭代器

(1)可迭代对象

什么是可迭代对象:

我们常见的数据量类型有list,str,tuple,set,dict以及文件句柄都是可迭代对象,因为他们中都包含了__iter__方法。

 1 l = [1,2,3]
 2 s = 'alex'
 3 t = (1,2,3)
 4 set = {1,2,3,4}
 5 dict = {'name':'twonss','age':20}
 6 
 7 f = open('log',encoding='utf-8',mode='w')
 8 print('__iter__' in dir(l))
 9 print('__iter__' in dir(s))
10 print('__iter__' in dir(t))
11 print('__iter__' in dir(set))
12 print('__iter__' in dir(dict))
13 print('__iter__' in dir(f))
View Code

结果:

 

PS:dir()是python内置的函数,可以打印出每个数据类型的所有可用方法

(2)迭代器

什么是迭代器:

我们常见的数据类型也都只是可迭代对象而已,但是文件句柄却是一个迭代器,迭代器内部不仅包含了__iter__方法,还包含了__next__方法,并且可以被for循环遍历,好处就是可以节省内存空间。

以文件句柄举例:

1 f = open('log',encoding='utf-8',mode='w')
2 print('__iter__' in dir(f))
3 print('__next__' in dir(f))
View Code

结果:

 

(3)将我们常见的数据类型变成迭代器:

 1 l = [1,2,3]
 2 s = 'alex'
 3 t = (1,2,3)
 4 set = {1,2,3,4}
 5 dict = {'name':'twonss','age':20}
 6 
 7 l1 = l.__iter__()
 8 s1 = s.__iter__()
 9 t1 = t.__iter__()
10 set1 = set.__iter__()
11 dict1 = dict.__iter__()
12 
13 print('__next__' in dir(l1))
14 print('__next__' in dir(s1))
15 print('__next__' in dir(t1))
16 print('__next__' in dir(set1))
17 print('__next__' in dir(dict1))
View Code

结果:

 

(4)迭代器的取值方式:

迭代器的取值方式用的就是__next__方法,每next一次只取一个值,想取完所有值就要一直next,直到取完报StopIteration错误为止。

示例1:

l1 = l.__iter__()
print(l1.__next__())
print(l1.__next__())
print(l1.__next__())
print(l1.__next__())

结果:

 

示例2:

l1 = l.__iter__()
while True:
    try:
        print(next(l1))  ##next() == __next__()
    except StopIteration:
        break

结果:

 

示例3:

l1 = l.__iter__()
for i in l1:
    print(i)

结果:

 

(5)判断是否是可迭代对象和迭代器的两种方法:

a、判断是否是可迭代对象的第一种方法:
 1 l = [1,2,3]
 2 s = 'alex'
 3 t = (1,2,3)
 4 set = {1,2,3,4}
 5 dict = {'name':'twonss','age':20}
 6 
 7 f = open('log',encoding='utf-8',mode='w')
 8 print('__iter__' in dir(l))
 9 print('__iter__' in dir(s))
10 print('__iter__' in dir(t))
11 print('__iter__' in dir(set))
12 print('__iter__' in dir(dict))
13 print('__iter__' in dir(f))
View Code

第二种方法: 

1 from collections import Iterable  #用解释器自带的模块
2 
3 print(isinstance(l,Iterable))
4 print(isinstance(s,Iterable))
5 print(isinstance(t,Iterable))
6 print(isinstance(set,Iterable))
7 print(isinstance(dict,Iterable))
8 print(isinstance(f,Iterable))
View Code
b、判断是否是迭代的第一种方法:
print('__next__' in dir(f))

第二种方法:

from collections import Iterator

print(isinstance(f,Iterator))

 

2、生成器:

生成器其实就是迭代器,可以被for循环遍历的一种函数,由于是是函数,所以会有返回值,但是在生成器里面不会用return返回结果,而是使用yield关键字去返回结果,yield每次都能返回一个或多个值,每遇到一个yield关键字时,函数就会挂起,下次执行时就会从它当前位置继续往下执行。

生成器格式:

 1 def func1():
 2     print('one')
 3     yield  1
 4     print('two')
 5     yield 2
 6     print('three')
 7     yield 3
 8     print('four')
 9     yield 4
10 
11 g = func1()  #这里执行函数的话不会去执行函数内部的代码,而是返回一个生成器对象
12 print(g)   #<generator object func1 at 0x0000000001DF3E60>
13 
14 如果想取到函数的执行结果的话必须像迭代器一样使用next()方法:
15 print(next(g))
16 print(next(g))
17 print(next(g))
View Code

结果:

PS:当然生成器的取值方式是和迭代器一样的,不止是next一次次的去取,也可以使用while循环和for循环去取。

send取值:

send取值和next取值的方式是一样的,不同的是,send在取下一个值时可以给上一个yield赋值,但是,send不能用于取第一个值,而且也不能给最后一个yield赋值。

示例:

def func1():
    print('one')
    num = yield  1
    print(num)
    print('two')
    yield 2
    print('three')
    yield 3

g = func1()
print(next(g))
print(g.send(123))  #123传给了num
print(next(g))
View Code

结果:

 

取值第一个值是用send取,结果报错:

 1 def func1():
 2     print('one')
 3     num = yield  1
 4     print(num)
 5     print('two')
 6     yield 2
 7     print('three')
 8     yield 3
 9 
10 g = func1()
11 print(g.send(123))
12 print(g.send(456))
13 print(next(g))
View Code

结果:

 

 

3、列表表达式和生成器表达式:

列表表达式:

例如生成一个列表,列表的内容为[python1期,python2期,python3期,...]

常规的生成方式是:

l1 = []
for i in range(1,11):
    l1.append('python%s期'%i)
print(l1)

使用列表表达式的生成方式是:

['python%s期' %i for i in range(1,11)]

结果:

列表表达式里还可以使用if判断:

比如判断打印大于5的每一期:

['python%s期' %i for i in range(1,11) if i > 5 ]

结果:

PS:在列表表达式里面,不仅可以做判断,还可以循环里面套循环

 

生成器表达式:

生成器表达式就是把列表表达式的[]换成了(),然后用next去取值,当然也 可以使用for循环:

ret = ( 'python%s期' %i for i in range(1,11))
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))

结果:

 

posted on 2018-06-07 16:55  花豆豆  阅读(161)  评论(0编辑  收藏  举报