• 迭代器和生成器


    迭代描述的就是一个重复的过程,之前学过的for和while,操作较多的就是列表,特点是:一个序列,有序,有索引。

    例如:
    1 l = ['a','b','c','d','e']
    2 i = 0
    3 while i < len(l):
    4     print(l[i])
    5     i+=1
    6 for i in range(len(l)):
    7     print(l[i])

    之前用的方法都是利用有下标和索引来取需要的值,但是无法对无下标的数据取值,所以我们现在需要用到了我们今天需要用到的迭代器:

    1 d = {'a':1,'b':2,'c':3}
    2 d.__iter__() #等同于iter(d)
    #只要被内置了__iter__方法和__next__方法的对象,就被称为可迭代对象。
    1 i = d.__iter__() #   i 就是迭代器
    2 print(i.__next__())
    3 print(i.__next__())
    这样我们就可以用迭代器来遍历字典了
    1 d = {'a':1,'b':2,'c':3}
    2 i = d.__iter__() #iter(d)
    3 while True:
    4     try:                               #抛出异常
    5        print(next(i))
    6     except StopIteration: ##捕捉一个叫StopIteration的异常
    7         break
    遍历列表
    1 l = ['a','b','c','d','e']
    2 i = l.__iter__()
    3 while True:
    4     try:                               #抛出异常
    5        print(next(i))
    6     except StopIteration:   #捕捉一个叫StopIteration的异常
    7         break
    8  
    for循环
    1 d = {'a':1,'b':2,'c':3}
    2 for k in d:   #,python中的for循环是将 in后面的对象先调用d.__iter__()方法,并且还自动增加了try,except来操作的。
    3     print()
    集合
    1 s = {1,2,3,4}
    2 for i in s:
    3     print(i)

    遍历一个文件

     1 with open('a.txt','r') as f:
     2     for line in f:
     3         print(line)
     4 
     5 f = open('a.txt','r')
     6 i = f.__iter__()
     7 while True:
     8     try:
     9         print(next(i))
    10     except StopIteration: 
    11         break
    12  
    13  
    14 f = open('a.txt','r')
    15 f.__next__
    16 f.__iter__
    17 print(f)                   #
    18 print(f.__iter__())  #f.__iter__()就是f本身
    19 for line in f:
    20     print(line)
    为什么要用迭代器:
    优点:
    1.迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)
    2.迭代器于列表比较,迭代器是惰性计算的,更节省内存
    缺点:
    1.无法获取迭代器的长度,使用不如列表索引取值灵活;
    2.迭代器是一次性的,只能往后取值,不能倒着取值
     
    查看可迭代对象与迭代器对象
     1 from collections import Iterable,Iterator #导入一个模块可以使用isinstance函数来判断一个数据的类型。
     2 isinstance('ssss',str) 
     3  
     4 s = 'hello'
     5 l = [1,2,3]
     6 t = (1,2,3)
     7 d = {'a':1}
     8 set1 = {1,2,3,4}
     9 f = open('a.txt')
    10  
    11 #都是可迭代的
    12 s.__iter__()
    13 l.__iter__()
    14 t.__iter__()
    15 d.__iter__()
    16 set1.__iter__()
    17 f.__iter__()
    18 print(isinstance(s,Iterable))
    19  
    20 print(isinstance(l,Iterable))
    21 print(isinstance(t,Iterable))
    22 print(isinstance(d,Iterable))
    23 print(isinstance(set1,Iterable))
    24 print(isinstance(f,Iterable))
    25  
    26 #查看是否是迭代器
    27 print(isinstance(s,Iterator))
    28 print(isinstance(l,Iterator))
    29 print(isinstance(t,Iterator))
    30 print(isinstance(d,Iterator))
    31 print(isinstance(set1,Iterator))
    32 print(isinstance(f,Iterator))

    生成器:(本质其实就是迭代器)

    生成器与return有何区别??
    return 只能返回一次函数就彻底结束了,而yield能返回多次值
    yield到底干了什么事情:
    1.yield把函数变成了生成器-->迭代器
    2.用return返回值能返回一次,而yield可以返回多次
    3.函数在暂停以及继续下一次运行时的状态由yield保存
    生成器就是一个函数,这个函数内包含有yield这个关键字
    1 def test():
    2    print('first') 
    3    yield 1 #return 1
    4 test()
    5 g = test()
    6 print(g)
    7 
    8 print(isinstance(g,Iterator))
    9 print(next(g))

    可以将函数作为生成器:

     1 from collections import Iterable,Iterator 
     2 def test():
     3    print('one') 
     4    yield 1 #return 1
     5    print('two') 
     6    yield 2#return 2
     7    print('three') 
     8    yield 3 #return 3
     9    print('four') 
    10    yield 4#return 4
    11     print('five')
    12     yield 5#return 5    
    13 test()
    14 g = test()
    15 
    16  
    17 res = next(g)
    18 print(res)
    19 res = next(g)
    20 print(res)
    21 res = next(g)
    22 print(res)
    23 res = next(g)
    24 print(res)
    25 res = next(g)
    26 print(res)
    27  
    28 #或者用
    29 for i in g:
    30     print(i)

    举例:

    1 def countdown(n):
    2     print('start countdown')
    3     while n>0
    4         yield n
    5         n-=1
    6     print('done')
    7 g = countdown(5)

    tail功能和grep功能      

    将grep 也改成生成器:
     1  def eater(name):
     2     print('%s start to eat food' %name)
     3     while True:
     4         food = yield
     5         print('%s get %s to start eat' %(name,food))
     6     print('done')
     7  
     8 e = eater('钢蛋')
     9 print(e)
    10 print(next(e))
    11 e.send('包子') #相当于next,但是给当前的yield传一个值
    练习一:
    生成器的应用
    把下述函数改成生成器的形式,执行生成器函数的到一个生成器g,然后每次g.send(url),打印页面的内容,利用g可以无限send
    1 def get(url):
    2         def index():
    3             return urlopen(url).read()
    4         return index
     1 """
     2 1.迭代器的应用
     3     文件名:a.txt,文件内容如下:
     4         apple 10 3
     5         tesla 100000 1
     6         mac 3000 2
     7         lenovo 30000 3
     8         chicken 10 3
     9 
    10         实现功能:cat a.txt |grep apple
    11             要求1:定义迭代器函数cat
    12             要求2:定义迭代器函数grep
    13             要求3:模拟管道的功能,将cat的处理结果作为grep的输入
    14 """
    15 # list_com = []
    16 
    17 def cat(file_path):
    18     with open(file_path,'r',encoding='utf-8') as f_cat:
    19         for line in f_cat:
    20             yield line
    21 
    22 def grep(text,cat_result):
    23     for line in cat_result:
    24         if text in line:
    25             yield line
    26 
    27 def my_com(command):
    28     list_com = []
    29     if '|' in command:
    30         list_temp = command.split('|')
    31         for i in list_temp:
    32             list_com.append(i.split( ))
    33         if list_com[0][0] == 'cat' and list_com[1][0]=='grep':
    34             c = cat(list_com[0][1])
    35             g = grep(list_com[1][1],c)
    36             return g
    37         else:
    38             print("请您注意命令的输入格式!!")
    39 
    40 def main():
    41     while True:
    42         try:
    43             try:
    44                 command = input("请输入您的命令例如:(cat a.txt |grep apple):")
    45                 print(next(my_com(command)))
    46             except StopIteration:
    47                 break
    48         except TypeError:
    49             print("您输入的命令有误请重新输入!!")
    50             continue
    51 if __name__ == '__main__':
    52     main()
    View Code

    练习二:

    迭代器的应用
    文件名:a.txt,文件内容如下:
    apple 10 3
    tesla 100000 1
    mac 3000 2
    lenovo 30000 3
    chicken 10 3

    实现功能:cat a.txt |grep apple
    要求1:定义迭代器函数cat
    要求2:定义迭代器函数grep
    要求3:模拟管道的功能,将cat的处理结果作为grep的输入
     1 """
     2 2.生成器的应用
     3     把下述函数改成生成器的形式,执行生成器函数的到一个生成器g,然后每次g.send(url),打印页面的内容,利用g可以无限send
     4     def get(url):
     5         def index():
     6             return urlopen(url).read()
     7         return index
     8 """
     9 from urllib.request import urlopen
    10 def get(url):
    11     while True:
    12         def index():
    13             return urlopen(url).read()
    14         url = yield index()
    15 
    16 
    17 def main():
    18     while True:
    19         url = input("请输入网页地址:")
    20         g = get(url)
    21         next(g)
    22         print(g.send(url))
    23 
    24 if __name__ == '__main__':
    25     main()
    View Code
     

     
     

     
  • 相关阅读:
    集群任务管理系统SGE的简明教程
    三代全长转录组测序和组装
    quota
    基因组转座元件
    单倍体
    什么是寒武纪、志留纪、泥盆纪、白垩纪
    对组装之后的三代基因组进行polish
    使用 PhyML 构建进化树
    PAML软件中的mcmctree命令估算物种分歧时间
    OrthoMCL及orthofinder 两种软件进行聚类分析
  • 原文地址:https://www.cnblogs.com/mojiexiaolong/p/6699299.html
Copyright © 2020-2023  润新知