Python基础(8)_迭代器、生成器、列表解析

一、迭代器

1、什么是迭代

  1 重复
  2 下次重复一定是基于上一次的结果而来

1 l=[1,2,3,4]
2 count=0
3 while count < len(l):
4     print(l[count])
5     count+=1
迭代举例

 

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保存的

生成器应用举例

 

 1 #模拟tail -f a.txt
 2 import time
 3 def tail(filepath,encoding):
 4     '''从文件读取最后一行内容'''
 5     with open (filepath,encoding='utf-8') as f:
 6         f.seek(0,2)
 7         while True:
 8             line=f.readline()
 9             if line:
10                 yield line
11             else:
12                 time.sleep(0.5)
13 def grep(lines,pattern):
14     '''guolv内容,如果有就返回'''
15     for line in lines:
16         if pattern in line:
17             #print(line)
18             yield line
19 
20 g=tail('homework01.txt')
21 g2=grep(g,'err0r')
22 g3=grep(g2,'404')
23 for i in g3:
24     print(i)
用生成器模拟tail -f |grep 'error'功能

三、列表解析

python的三元运算格式如下:

  result=值1 if x<y else 值2    这个是什么意思呢,就是结果=值1 if 条件1 else 值2

列表解析:

  用三元表达式,将结果写入列表,即为列表解析

 

 

列表解析实例:

 1 要求:列出1~10所有数字的平方
 2 ####################################################
 3 1、普通方法:
 4 >>> L = []
 5 >>> for i in range(1,11):
 6 ...     L.append(i**2)
 7 ... 
 8 >>> print L
 9 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
10 ####################################################
11 2、列表解析
12 >>>L = [ i**2 for i in range(1,11)]
13 >>>print L
14 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 1 要求:列出1~10中大于等于4的数字的平方
 2 ####################################################
 3 1、普通方法:
 4 >>> L = []
 5 >>> for i in range(1,11):
 6 ...     if i >= 4:
 7 ...         L.append(i**2)
 8 ... 
 9 >>> print L
10 [16, 25, 36, 49, 64, 81, 100]
11 ####################################################
12 2、列表解析
13 >>>L = [ i**2 for i in range(1,11) if i >= 4 ]
14 >>>print L
15 [16, 25, 36, 49, 64, 81, 100]
 1 要求:列出"/var/log"中所有已'.log'结尾的文件
 2 ##################################################
 3 1、普通方法
 4 >>>import os
 5 >>>file = []
 6 >>> for file in os.listdir('/var/log'):
 7 ...     if file.endswith('.log'):
 8 ...         file.append(file)
 9 ... 
10 >>> print file
11 ['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']
12 ##################################################
13 2.列表解析
14 >>> import os
15 >>> file = [ file for file in os.listdir('/var/log') if file.endswith('.log') ]
16 >>> print file
17 ['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']

四、生成器解析

 1 #############################################
 2 egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析
 3 
 4 #############################################
 5 
 6 laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式
 7 print(laomuji)
 8 print(next(laomuji)) #next本质就是调用__next__
 9 print(laomuji.__next__())
10 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)])

 

 

posted @ 2017-06-16 16:54  hedeyong11  阅读(224)  评论(1编辑  收藏  举报