zoukankan      html  css  js  c++  java
  • 15 迭代器、生成器、模块和包

    第16节 迭代器、生成器


    作业解答

    
    
    import os
    ​
    if not os.path.exists('my_tesr.txt'):   # 判断文件是否存在
        file = open('my_test.txt', 'w+', encoding='utf-8')
        
        try:
            my_dict = {'name': 'xiaojiu'}
            file.write(my_dict['name'])
            
        except Exception as e:
            print(e)
            
        finally:
            file.close()
            print('文件正常关闭')
            
    # 文件存在则不会运行try 

    一, 推导表达式

    1,列表推导
    • 循环添加:

      >>> li = []
      >>> for i in range(10):
      ...     li.append(i)
      ... 
      >>> li
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    • 列表推导:

      li = [i for i in range (10)]
    • 列表推导+条件判断:

      li2 = [i for i in range(10) if i % 2 == 0]
    • 列表推导+三目运算:

      li3 = [i if i % 2 == 0 else 0 for i in range(10)]
    2,集合和字典推导
    • 集合推导:

      se = {i for i in range(10)}
    • 字典推导:

      li = [1,2,3,4,5,6,7,8,9,10]
      di = {i:j for i, j in enumerate(li)}

    二,生成器

    1,创建生成器的两种方法
    • 列表推导式的[]改成()
      >>> tu = (i for i in range(1,11))
      >>> next(tu)
      1
      >>> next(tu)
      2
      >>> next(tu)
      3
    • 在函数里面加上 yield
      >>> def func(num):
          a = 0
          while a < num:
              yield a
              a += 1>>> b = func(10)
      >>> next(b)
      0
      >>> next(b)
      1
      >>> next(b)
      2
    2, yield运行规则
    • yield 一个对象:返回这个对象、暂停这个对象、等待下次next重新激活

    • 注意:

      yield表达式只能在函数中使用,在函数体中使用yield 表达式可以使函数成为一个生成器

      yield 可以返回表达式结果,并且暂定函数执行,直到next激活下一个yield

    Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果,从而节省大量的空间,这也是生成器的主要好处

    三,迭代器

    1,区分可迭代对象和迭代器
    • 可迭代对象: Iterable

      可迭代对象能用for循环进行遍历

      可以使用 isinstance() 判断一个对象是否是 Iterable 对象

      >>> from collections import Iterable,Iterator
      >>> li = [1,2,3,4,5]
      >>> isinstance(li,Iterable)
      True
      >>> di = {'a':1,'b':2}
      >>> isinstance(di,Iterable)
      True
    • 迭代器: Iterator

      迭代器不仅可以通过for进一行遍历,可以通过next取值

      可以使用 isinstance() 判断个对象是否是 Iterator对象

      >>> from collections import Iterable,Iterator
      >>> li = [1,2,3,4,5]
      >>> li1 = iter(li)
      >>> isinstance(li1,Iterator)
      True
      >>> tu = (1,2,3,4,5)
      >>> isinstance(tu,Iterator)
      False
    2,迭代

    for 迭代变量 in 可迭代对象,每一次循环都会自动让“迭代变量”指向“下一个元素” 。

    # 例1
    li = [1,2,3,4,5]
    for i in li:
        print(i)
    # 例2
    li = [1,2,3,4,5]
    index = 0
    var = None
    while index < len(li):
        var = li[index]
        print(var)
        index += 1
        
    两次打印结果都一样:
    1
    2
    3
    4
    5
    3,for实现原理
    li = [1,2,3,4,5]
    li2 = iter(li)
    try:
        while True:
            var = next(li2)
            print(var)
    ​
    except StopIteration:
        pass
        
    打印结果:
    1
    2
    3
    4
    5
    4,从可迭代对象生成一个迭代器

    迭代器 = iter(可迭代对象)

    下个值 = next(迭代器)

    5,自定义迭代器

    迭代器对象本身需要支持以下两种方法,它们一起构成迭代器协议:

    iterator.__iter__()
    ​
    iterator.__next__()

    取值:

    next(iterator)
    ​
    iterator.__next__()

    注意:如果迭代器值取完之后,会返回StopIteration 错误

    四,模块

    1,模块的导入
    • 在python中,模块就是一个py文件,可以使用下面两种方法导入

      import datetime
      
      from datetime import datetime (as this_datetime)
      
      注意:datetiame是一个常用的时间处理模块
    • 在同一目录下,可直接使用上面两种方法去导入

      在不同目录下,需要使用 sys.path 添加路径sys.path.append('path')

    • import sys
      sys.path.append('/home/pyvip/pycharm/学员信息管理系统')
      import zcm
      zcm.func1()
      zcm.func2()
    • 在python3中导入后,会在当前路径下生成一个pycache 文件夹

    2,导入语法 与 导入路径
    • import 模块名

      直接导入

      使用时模块名.函数名()

    • import 模块名 as 新名字

      导入以后,重新命名

      使用新名字.函数名()

    • from 模块名 import 函数名

      部分导入,导入模块内部的东西,而不要模块可以在模块里用一个变量 __all__控制被导入函数

      __all__ = ['func1','func2']
      
      def func1():
          print('这是第一行')
      def func2():
          print('这是第二行')
      def func3():
          print('这是第三行')
      from zcm import *
      
      func1()
      func2()
      
      打印结果:
      这是第一行
      这是第二行
    3,if __name__ == '__main__'
    • __name__

      python会自动的给模块加上这个属性

      如果模块是被直接调用的,则__name__ 的值是__main__

      否则就是该模块的模块名

    • if __name__ == '__main__'

      该语句可以控制代码在被其他模块导入时不被执行

      def func1():  
          print('这是第一行')
      def func2():
          print('这是第二行')
      def func3():
          print('这是第三行')
          
          
      if name == 'main':
          print('不想被调用')
      import zcm
      zcm.func1()
      
      打印结果:
      这是第一行

    五,包和包管理

    1,包概念:

    把很多模块放到一个文件夹里面,就可以形成一个包

    导包

    import test.zcm
    test.zcm.func1()
    ​
    import test.zcm as t    # test是文件夹,zcm是py文件
    t.func1()
    ​
    from test import zcm
    zcm.func1()
    ​
    from test import zcm as t
    t.func1()

    导入全部包 *

    __all__ = ['zcm']       # 这句代码必须要写到init里面
    
    from test import *
    zcm.func1()
    导入包方法:
    # 例子1
    # 在包里面的 __init__文件里定义函数方法
    def initfunc():
        print('这是initfunc')
    # 例子1
    import pp        # pp是包文件夹的名字
    pp.initfunc()
    
    打印结果:
    这是initfunc
    # 例子2
    # 在包里面的 __init__文件里定义函数方法
    __all__ = ['initfunc']
    
    def initfunc():
        print('这是initfunc')
    # 例子2
    form pp import *
    
    initfunc()
    
    打印结果:
    这是initfunc
    2,包管理:

    当把很多模块放在文件中时,为了方便引用包中的模块,引入了包管理

    3,__init__.py

    在包管理中,加入此模块,则包名可以直接通过属性访问的方式,访问此模块内的对象,文件内容可以为空

    4,相对路径导入

    在包管理中,可以通过. (一个点) 和 .. (两个点)分别来导入同层和上一层的模块

  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/zcmq/p/9114484.html
Copyright © 2011-2022 走看看