zoukankan      html  css  js  c++  java
  • python进阶学习chapter03(迭代相关)

    • 如何实现可迭代对象和迭代器对象
    • 如何实现反向迭代
    • 如何实现在一个for循环中迭代多个可迭代对象
    • 对迭代器进行切片操作
    • itertools总结

    一、如何实现可迭代对象和迭代器对象

    重要概念!!!迭代器,可迭代对象,生成器,很容易绕晕了。

    凡是可以使用for进行循环的就是可迭代对象,其中可以通过next方法逐步输出的就是迭代器,生成器的形成有两种:一种是把列表生成式改成(),一种是带有yield语句的。

    具体的可以看:http://www.cnblogs.com/alex3714/articles/5765046.html

    接下来进入主题:

     如何实现一个迭代器?

    #实现一个迭代器
    from collections import Iterator,Iterable
    #构造迭代器
    class WeatherIterator(Iterator):
        def __init__(self,cities):
            self.cities = cities
            self.index = 0
    
        def getweather(self,city):
            r = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=' + city)
            dict_data = r.json()['data']['forecast'][0]
            return "%s:%s,%s" % (city,dict_data['low'],dict_data['high'])
    
        def __next__(self):
            if self.index == len(self.cities):
                raise StopIteration
            city = self.cities[self.index]
            self.index += 1
            return self.getweather(city)
    
    class WeatherIterable(Iterable):
        def __init__(self,cities):
            self.cities=cities
        def __iter__(self):
            return WeatherIterator(self.cities)
    #生成迭代器对象
    weatheriterator = WeatherIterator([u'北京',u'南京',u'上海'])
    #迭代器对象调用next()方法
    # print(weatheriterator.__next__())
    # print(weatheriterator.__next__())
    # print(weatheriterator.__next__())
    for x in weatheriterator:
        print(x)
    

      Python 的迭代协议需要 _iter_() 方法返回一个实现了 _next_() 方法的迭代器对象。

    二、如何实现反向迭代

    参考:http://www.cnblogs.com/2bjiujiu/p/7248827.html

    问题引入:

     实现一个连续的浮点数发生器,FloatRange,根据给定范围(start, end) 和步进值,产生一些列的浮点数,例如:FloatRange(3,4,0.2),将产生下列序列:

           正向:3.0 3.2 …… 4.0

           反向:4.0 3.8 …… 3.0

    实现思路:

    方法一、列表翻转(但是改变了原列表)

    l = [1, 2, 3, 4, 5, 6]
    l.reverse()
    for i in l:
        print(i)
    

      方法二、列表切片(但是得到了和列表等大的列表,浪费空间)

    l = [1, 2, 3, 4, 5, 6]
    for i in l[::-1]:
        print(i)
    

      方法三、reversed()函数,返回一个反转的迭代器

    l = [1, 2, 3, 4, 5, 6]
     
    for i in reversed(l):
        print(i)
    

      for循环是调用的_iter_方法,反向迭代调用的是_reversed_方法

    class FloatRange(object):
        def __init__(self, start, end, step):
            self.dot = self.__get_dot_num(step)
            # 有多少个小数点就乘以10的多少次幂,因为浮点数运算不准确,换算成整形数进行计算
            self.start = start*pow(10, self.dot)
            self.end = end*pow(10, self.dot)
            self.step = step*pow(10, self.dot)
             
        def __get_dot_num(self, step):
            # 计算step有多少个小数点
            if isinstance(step, int):
                return step
            else:
                # 通过round实现计算有多少位小数,首创
                for dot in range(len(str(step))+1):
                    if step == round(step, dot):
                        return dot
     
        def __iter__(self):
            # 正向迭代
            while self.start <= self.end:
                yield self.start/pow(10, self.dot)
                self.start += self.step
     
        def __reversed__(self):
            # 反向迭代
            while self.end >= self.start:
                yield self.end/pow(10,self.dot)
                self.end -= self.step
     
    if __name__ == '__main__':
         
        float_num_1 = FloatRange(2, 5, 0.1)
        float_num_2 = FloatRange(2, 5, 0.1)
         
        # 正向迭代
        for i in float_num_1:
            print(i)
             
        print('_'*60)
         
        # 反向迭代
        for x in reversed(float_num_2):
            print(x)
    

      

    三、如何实现在一个for循环中迭代多个可迭代对象

    问题引入:

    1、如何同时迭代三个列表(并行):某班期末考试成绩分别存在语文、数学、英语三个列表中,计算每个学生的总分

    2、如何依次迭代三个列表(串行):四个班级的英语成绩分别存在四个列表中,统计四个班高于90分的总人数

    问题1、可以通过索引,也可以使用zip函数将三个列表打包成一个元组

    from random import randint
     
     
    def get_result(chinese, math, english):
        total = []
        # 循环索引进行取值,毕竟列表等长且成绩对应
        for index in range(len(chinese)):
            total.append(chinese[index] + math[index] + english[index])
        return total
    或者:
    def get_result(chinese, math, english):
        total = []
        # 通过zip函数进行迭代,实现同时迭代 3 个对象
        for c, m, e in zip(chinese, math, english):
            print(c, m, e)
            total.append(c + m + e)
        return total
    

     问题2、通过itertools中的chain

     

    from random import randint
    from itertools import chain
     
     
    def get_result(e1, e2, e3):
        # 通过chain函数进行连续窜行迭代3个列表
        for i in chain(e1, e2, e3):
            print(i)
    

      

    四、对迭代器进行切片操作

    问题引入:如何读取某个文件的100~200行的内容呢

    是否可以:

    f=open()

    f[100:200]

    方法一、首先使用readlines()读取全部文件,然后再用切片操作,但是文件很大的时候就不适用

    f = open()
    f_all = f.readlines()
     
    for i in f_all[100:200]:
           print(i)
    

     方法二、使用itertools的islice方法

    f = open()
     
    f_need = islice(f, 100, 200)
     
    for i in f_need:
        print(i)
    

     五、itertools模块的总结

    参见廖雪峰官网

  • 相关阅读:
    Android6.0以后动态增加权限
    Failed to resolve: junit:junit:4.12
    tflite
    error: undefined reference to `cv::imread(std::string const&, int)'
    Makefile
    tf模型可视化工具
    linux c++下遍历文件
    mobilenetV3
    centos7安装mxnet
    chrome的一些插件
  • 原文地址:https://www.cnblogs.com/mesunyueru/p/9196217.html
Copyright © 2011-2022 走看看