迭代器,生成器,列表推导式,生成器表达式

迭代器:

可迭代对象:内部含有__inter__的python

可迭代对象不能取值,由于内部没有__next__()方法app

可迭代对象------>迭代器:ssh

  boj.__iter__()或者inter(obj)ide

实现的原理相似于往弹匣里面装子弹,而后一个一个往外发射函数

经过__iter__()来获取到迭代器spa

1 stes = {1, 2, 3, 4, 5, 67, 7} 2 print(stes.__dir__()) 3 s = stes.__iter__() 4 print(s)
迭代器

打印结果code

1 ['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__sub__', '__rsub__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__isub__', '__iand__', '__ixor__', '__ior__', '__len__', '__contains__', '__new__', 'add', 'clear', 'copy', 'discard', 'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', '__reduce__', 'remove', '__sizeof__', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__'] 2 <set_iterator object at 0x0000000001EF1480>
打印结果

经过__next__()来拿到元素,一次只能拿一个,若是最后一个元素以后继续使用__next__(),会报错:StopIterationorm

 1 stes = {1, 2, 3, 4, 5, 67, 7}  2 s = stes.__iter__()  3 print(s.__next__())  4 print(s.__next__())  5 print(s.__next__())  6 print(s.__next__())  7 print(s.__next__())  8 print(s.__next__())  9 print(s.__next__()) 10 print(s.__next__())
__next__()

打印结果为:对象

 1 1
 2 2
 3 3
 4 4
 5 5
 6 67
 7 7
 8 Traceback (most recent call last):  9   File "C:/Python/Module/regex_test.py", line 53, in <module>
10     print(s.__next__()) 11 StopIteration
打印结果

判断是否为迭代器:blog

  1.经过__iter__(),__next__()是否在obj.__dir__()

1 with open('01','w', encoding='utf-8') as f: 2     print('__iter__' in dir(f)) 3     print('__next__' in dir(f)) 4 """
5 打印结果: 6 True 7 True 8 说明文件句柄自己是一个迭代器 9 """
dir方法

  2.经过collections模块中的Iterable来判断

 1 from collections import Iterable  2 from collections import Iterator  3 
 4 l = [1,2,3,4]  5 print(isinstance(l, Iterable))    # 判断是否为可迭代对象
 6 print(isinstance(l, list))  7 
 8 
 9 """
10 打印结果: 11 True 12 True 13 """
14 
15 l = [1,2,3,4] 16 print(isinstance(l, Iterable)) 17 print(isinstance(l, Iterator)) 18 print(isinstance(l, list)) 19 
20 """
21 打印结果: 22 True 23 False 24 True 25 """
Iterable

 

生成器:

生成器实质就是迭代器,在python中有三种方式来获取生成器:

1. 经过生成器函数
2. 经过各类推导式来实现来生成器
3. 经过数据的转换也能够获取生成器

 生成器是咱们本身用Python代码写的迭代器:

 1 def gener():  2     print(111)  3     yield 222
 4     print(333)  5     yield 444
 6     print(555)  7     yield 666
 8     print(777)  9     yield 888
10 
11 
12 gen = gener() 13 print(gen) 14 
15 # 打印结果为:<generator object gener at 0x0000000001E74D00>
生成器

生成器函数和普通的函数的区别就是把return换成了yield

 yield 和return区别

  1. 若是函数中包含了yield, 这个函数是一个生成器函数. 执行函数的时候是: 生成器

  2. 生成器执行__next__(). 执行到下一个yield

  3. yield的做用和return基本相同. 可是,只负责返回. 不会结束函数

  4. return,结束函数.

经过obj__next__()方法取值:

 1 def gener():  2     print(111)  3     yield 222
 4     print(333)  5     yield 444
 6     print(555)  7     yield 666
 8     print(777)  9     yield 888
10 
11 
12 gen = gener() 13 print(gen) 14 ret = gen.__next__()    # 这里的ret至关于执行函数,直行道yield是返回yield的返回值
15 print(ret) 16 ret1 = gen.__next__() 17 print(ret1) 18 ret2 = gen.__next__() 19 print(ret2) 20 ret3 = gen.__next__() 21 print(ret3) 22 
23 """
24 打印结果: 25 <generator object gener at 0x0000000000814D00> 26 111 27 222 28 333 29 444 30 555 31 666 32 777 33 888 34 """
生成器取值

生成器还能够经过send()方法进行取值个传值,不过使用send方法时要注意的是:

  1.第一个yield必须经过__next__()方法取得

  2.最后一个yield不能经过send()方法传值.

 1 def gener():  2     print(111)  3     a = yield 222
 4     print(a)  5     print(333)  6     b = yield 444
 7     print(b)  8     print(555)  9     c = yield 666
10     print(c) 11     print(777) 12     yield 888
13 
14 
15 gen = gener() 16 print(gen) 17 ret = gen.__next__() 18 print(ret) 19 ret1 = gen.send('<<>>') 20 print(ret1) 21 ret2 = gen.send('<<>>') 22 print(ret2) 23 ret3 = gen.send('<<>>') 24 print(ret3) 25 
26 """
27 打印结果: 28 <generator object gener at 0x0000000001DD4D00> 29 111 30 222 31 <<>> 32 333 33 444 34 <<>> 35 555 36 666 37 <<>> 38 777 39 888 40 """
send()方法

使用send()方法时要注意的是要传参,否则会报错

send和__next__() 区别:

  send能够给上一个yield 的位置传递值 , 第一个必须用__next__()

  __next__() 不能传值

列表推导式:

须要一个列表,里面包含1到13的数字,第一反应是:

1 l = [] 2 
3 for i in range(1, 14): 4  l.append(i) 5 print(l) 6 # 打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
生成一个列表

 咱们来看这样一段代码:

1 l = [ i for i in range(1,14)] 2 print(l) 3 
4 #打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
列表推导式

有这样一个需求,经过列表推导式来筛选憨厚两个e的名字:

1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], 2          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] 3 name2 = [name for i in names for name in i if name.count('e') == 2] 4 print(name2) 5 
6 # 打印结果:['Jefferson', 'Wesley', 'Steven', 'Jennifer']
筛选模式

l = [变量(加工后的变量) for 变量 in iterable] 循环模式

l = [变量(加工后的变量) for 变量 in iterable if 条件] 筛选模式

相似于真样的式子被成为列表推导式.

优势:

1,节省代码,一行搞定.

2,看着高大上.

缺点:

很差排错.

总体:

凡是用列表推导式构造的列表对象,用其余方式均可构建.,很是复杂的列表,列表推导式是构建不出的,

列表推导式比较有魔性.

生成器表达式:

生成器表达式和列表推导式基本同样,惟一的区别就是把列表推推导式的方括号变成圆括号:

1 l = ( i for i in range(1,14)) 2 print(l) 3 
4 #打印结果:<generator object <genexpr> at 0x0000000001F24D00>
生成器表达式

 

一样的也有两种模式:

循环模式和筛选模式

相关文章
相关标签/搜索