一、迭代器
1、什么是迭代
1 重复
2 下次重复一定是基于上一次的结果而来
l=[,,,]
count=
while count < len(l):
print(l[count])
count+=
迭代举例
2、可迭代对象
可进行.__iter__()操作的为可迭代对象
#print(isinstance(str1,Iterable)),判断str1是否是可迭代对象
3、迭代器
进行.__iter__()操作操作后的结果为迭代器
iter1=obj.__iter__() #iter1为迭代器
优点:
1 提供了一种不依赖于索引的取值方式
2 惰性计算,节省内存
缺点:
1 取值不如按照索引取值方便
2 一次性,只能往后取,不能回退
3 无法获取长度
迭代器的应用:
1.提供了一种不依赖索引的统一的迭代方法
2. 惰性计算,比如取文件的每一行
4、迭代器对象
可进行.__next__()操作的为可迭代对象
#print(isinstance(str1,Iterator)),判断str1是否是迭代器对象
二、生成器
生成器函数:函数体内包含有yield关键字
生成器:生成器函数执行的结果是生成器
yield的功能:
1.与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值
2.为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器
3.遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的
生成器应用举例
#模拟tail -f a.txt
import time
def tail(filepath,encoding):
'''从文件读取最后一行内容'''
with open (filepath,encoding='utf-8') as f:
f.seek(,)
while True:
line=f.readline()
if line:
yield line
else:
time.sleep(0.5)
def grep(lines,pattern):
'''guolv内容,如果有就返回'''
for line in lines:
if pattern in line:
#print(line)
yield line g=tail('homework01.txt')
g2=grep(g,'err0r')
g3=grep(g2,'')
for i in g3:
print(i)
用生成器模拟tail -f |grep 'error'功能
三、列表解析
python的三元运算格式如下:
result=值1 if x<y else 值2 这个是什么意思呢,就是结果=值1 if 条件1 else 值2
列表解析:
用三元表达式,将结果写入列表,即为列表解析
列表解析实例:
要求:列出1~10所有数字的平方
####################################################
、普通方法:
>>> L = []
>>> for i in range(,):
... L.append(i**)
...
>>> print L
[, , , , , , , , , ]
####################################################
、列表解析
>>>L = [ i** for i in range(,)]
>>>print L
[, , , , , , , , , ]
要求:列出1~10中大于等于4的数字的平方
####################################################
、普通方法:
>>> L = []
>>> for i in range(,):
... if i >= :
... L.append(i**)
...
>>> print L
[, , , , , , ]
####################################################
、列表解析
>>>L = [ i** for i in range(,) if i >= ]
>>>print L
[, , , , , , ]
要求:列出"/var/log"中所有已'.log'结尾的文件
##################################################
、普通方法
>>>import os
>>>file = []
>>> for file in os.listdir('/var/log'):
... if file.endswith('.log'):
... file.append(file)
...
>>> print file
['anaconda.ifcfg.log', 'Xorg.0.log', 'anaconda.storage.log', 'Xorg.9.log', 'yum.log', 'anaconda.log', 'dracut.log', 'pm-powersave.log', 'anaconda.yum.log', 'wpa_supplicant.log', 'boot.log', 'spice-vdagent.log', 'anaconda.program.log']
##################################################
.列表解析
>>> import os
>>> file = [ file for file in os.listdir('/var/log') if file.endswith('.log') ]
>>> print file
['anaconda.ifcfg.log', 'Xorg.0.log', 'anaconda.storage.log', 'Xorg.9.log', 'yum.log', 'anaconda.log', 'dracut.log', 'pm-powersave.log', 'anaconda.yum.log', 'wpa_supplicant.log', 'boot.log', 'spice-vdagent.log', 'anaconda.program.log']
四、生成器解析
#############################################
egg_list=['鸡蛋%s' %i for i in range()] #列表解析 ############################################# laomuji=('鸡蛋%s' %i for i in range())#生成器表达式
print(laomuji)
print(next(laomuji)) #next本质就是调用__next__
print(laomuji.__next__())
print(next(laomuji))
总结:
1.把列表解析的[]换成()得到的就是生成器表达式
2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。
例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和:
sum(x ** 2 for x in xrange(4))
而不用多此一举的先构造一个列表:
sum([x ** 2 for x in xrange(4)])