• 解析式、表达式


    解析式

    标签(空格分隔): Python-解析式



    一、解析式

    1、列表解析式

    • 生成一个列表, 元素 0~9,最每一个元素自增 1后,求平方,返回列表

      # 普通实现
      lst = []
      for i in range(10):
          lst.append((i+1)**2)
      
      # 列表解析式实现
      lst = [(i+1)**2 for i in range(10)]
      
    • 语法

      • [返回值 for 元素 in 可迭代对象 if 条件]
      • 使用中括号 [], 内部式 for 循环 , if 条件语句可选
      • 立即返回一个新列表
    • 列表解析式是一种语法糖

      • 编译器会优化,不会因为简写而影响效率, 反而因优化而提高了效率
      • 减少程序员工作量,减少出错
      • 简化代码,增加可读性

    列表解析式进阶

    • 语法

      • [expr for i in iterable1 for j in iterable2]
      • 等价写法:
      lst = []
      for i in itersble1:
          for j in iterable2:
              lst.append((x, y))
      
      
    • 语法

      • [expr for i in iterable1 if cond1 if cond2]
      • 等价写法:
      lst = []
      for i in itersble1:
          if cond1:
              if cond2:
                  lst.append(i)
                  
      >>> 等价于
      for i in iterable1:
          if cond1 and cond2:
              lst.append(i)
      
      

    练习题

    • 返回 1-10 平方的列表

      print([i**2 for i in range(1, 11)])
      
    • 有一个列表 lst = [1, 4, 9, 16, 2, 5, 10, 15],生成一个新列表,要求新元素是lst相邻2项的和

      lst = [1, 4, 9, 16, 2, 5, 10, 15]
      length = len(lst)
      print([lst[i]+lst[i+1] for i in range(length-1)])
      
    • 打印 九九乘法表

      [print("{}x{}={:>{}}{}".format(j, i, i*j, 1 if j == 1 else 2, "
      " if i==j else ' '), end="") for i in range(1, 10) for j in range(1, i+1)]
      
    • 打印ID, 要求左边4位是从1开始的整数,右边是10位随机小写英文字母,中间以点分隔; 打印前100个

      import string
      from random import choice
      [print(".".join(["{:0>4}".format(i), "".join(choice(string.ascii_lowercase) for _ in range(10))])) for i in range(100)]
      

    2、集合解析式

    语法

    • {返回值 for 元素 in 可迭代对象 if 条件}
    • 列表解析式的中括号换成大括号就可以了
    • 立即返回一个集合

    用法

    • {(x, x+1) for x in range(10)}
    • {for x in range(10)} # 错误用法,集合的元素必须是可哈希的

    3、字典解析式

    语法

    • {返回值 for 元素 in 可迭代对象 if 条件}
    • 列表解析式的中括号换成大括号就可以了
    • 使用 key:value 形式
    • 立即返回一个字典

    用法

    • {x: (x, x+1) for x in range(10)}
    • {x: [x, x+1] for x in range(10)}
    • {(x,): [x, x+1] for x in range(10)}
    • {[x]: [x, x+1] for x in range(10)} # 错误用法,不可哈希
    • {chr(0x41+x): x**2 for x in range(10)}
    • {str(x): y for i in range(3) for y in range(4)}

    二、生成器表达式

    1、生成器表达式语法

    • (返回 for 元素 in 可迭代对象 if 对象)
    • 列表解析式的中括号换成小括号就可以了
    • 返回一个生成器 (可迭代对象,迭代器)

    使用 内建函数 next() 来判断一个对象是不是生成器
    使用 内建函数 iter() 将一个对象编程一个生成器对象


    2、实例

    # 生成器表达式使用
    
    g = ("{:04}".format(i) for i in range(1, 11))
    next(g)
    
    for i in g:
        print(i)
        
    print("~~~~~~~~~~~")
    for i in g:
        print(i)
    
    # 总结
    # - 延迟计算
    # - 返回一个迭代器,可以迭代
    # - 从前到后走完一遍后,不能回头
    
    # 列表生成器
    
    g = ["{:04}".format(i) for i in range(1, 11)]
    next(g)
    
    for i in g:
        print(i)
        
    print("~~~~~~~~~~~")
    for i in g:
        print(i)
    
    # 总结
    # - 立即计算
    # - 返回的不是一个迭代器,而是一个可以迭代对象列表
    # - 从前到后走完一遍后,可以重新回头迭代
    

    三、和列表解析式的区别

    • 生成器表达式是按需计算 (或惰性求值、延迟计算) --- 需要的时候才计算
    • 列表解析式是立即返回值

    四、和列表解析式的对比

    1、计算方式

    • 生成器表达式延迟计算,列表解析式立即计算

    2、内存占用

    • 单从返回值本身来说,生成器表达式省内存, 列表解析式返回新的列表
    • 生成器没有数据,内存占用极少,但是使用的时候,虽然一个个返回数据,但是合起来占用的内存也差不多
    • 列表解析式构造新的列表,立即返回,在同一时间下需要占用大量内存; 而生成器则分散了计算时间和占用的空间

    3、计算速度

    • 单从计算时间看,生成器表达式耗时非常短,列表解析式耗时长
    • 但是生成器本身并没有返回任何值,只返回了一个生成器对象
    • 列表解析式构造并返回一个新的列表

    五、总结

    • python2 引入 列表解析式
    • python2.4 引入 生成器表达式
    • python3 应用集合、字典解析式、并迁移到了 2.7

    1、一般来说,应该多用解析式,因为解析式简短、高效 (解释器会做优化)
    2、如果一个解析式非常复杂,难以读懂,要考虑拆解成 for 循环

    生成器和迭代器是不同的对象,但都是可迭代对象

  • 相关阅读:
    c#中取整和取余
    安装程序无法创建新的系统分区,也无法定位现有的系统分区
    经销商、代理商、分销商的关系
    关于WinPE安装操作系统
    SQL Server 2008 数据库同步的两种方式 (发布、订阅)
    SQL Server 2008 数据库同步的两种方式 (发布、订阅)
    通过SQL Server 2008数据库复制实现数据库同步备份
    SQL Server 2008 R2数据库镜像部署图文教程
    SQL 2008提供几种数据同步方式
    Microsoft Sync Framework下的快速开发同步程序
  • 原文地址:https://www.cnblogs.com/jingru-QAQ/p/11415760.html
Copyright © 2020-2023  润新知