Python——各种推导式

Python——各种推导式,第1张

Python——各种推导式

文章目录
      • Python——各种推导式
        • 列表推导式
        • 字典推导式
        • 元组推导式(生成器)
        • 集合推导式
        • 函数推导式
        • 嵌套推导式(不推荐)
        • 大数据量推导式

列表推导式
  • 格式:
    列表推导式格式为:

    [表达式 for 变量 in 列表]
    [out_exp_res for out_exp in input_list]
    
    或者
    
    [表达式 for 变量 in 列表 if 条件]
    [out_exp_res for out_exp in input_list if condition]
    
    • out_exp_res:列表生成元素表达式,可以是有返回值的函数。


    • for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。


    • if condition:条件语句,可以过滤列表中不符合条件的值。


  • 示例:
    过滤掉长度小于或等于3的字符串列表,并将剩下的转换成大写字母:

    >>> names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
    >>> new_names = [name.upper() for name in names if len(name)>3]
    >>> print(new_names)
    ['ALICE', 'JERRY', 'WENDY', 'SMITH']
    

    计算 30 以内可以被 3 整除的整数:

    >>> multiples = [i for i in range(30) if i % 3 == 0]
    >>> print(multiples)
    [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
    
字典推导式
  • 格式:
    字典推导基本格式:

    { key_expr: value_expr for value in collection }{ key_expr: value_expr for value in collection if condition }
    
  • 示例:
    使用字符串及其长度创建字典:

    listdemo = ['Google','Runoob', 'Taobao']
    # 将列表中各字符串值为键,各字符串的长度为值,组成键值对
    >>> newdict = {key:len(key) for key in listdemo}
    >>> newdict
    {'Google': 6, 'Runoob': 6, 'Taobao': 6}
    

    提供三个数字,以三个数字为键,三个数字的平方为值来创建字典:

    >>> dic = {x: x**2 for x in (2, 4, 6)}
    >>> dic
    {2: 4, 4: 16, 6: 36}
    >>> type(dic)
    <class 'dict'>
    
元组推导式(生成器)
  • 格式:
    元组推导式的基本格式:

    (expression for item in Sequence )(expression for item in Sequence if conditional )
    

    元组推导式和列表推导式的用法也完全相同,只是元组推导式是用 () 圆括号将各部分括起来,而列表推导式用的是中括号 [],另外元组推导式返回的结果是一个生成器对象。


  • 示例:
    我们可以使用下面的代码生成一个包含数字 1~9 的元组:

    >>> a = (x for x in range(1,10))
    >>> a
    <generator object <genexpr> at 0x7faf6ee20a50>  # 返回的是生成器对象
    >>> tuple(a)       # 使用 tuple() 函数,可以直接将生成器对象转换成元组
    (1, 2, 3, 4, 5, 6, 7, 8, 9)
    
  • 注意
    在 Python 中,生成器是一种特殊的可迭代对象,它会延迟加载元素,直到被请求才会加载。


    这在处理大量数据时会非常高效,它能提升存储效率。


    相比之下,list 对象为了方便计数和索引,一次性创建所有的元素。


    所以跟生成器相比,在元素个数相同时,list 需要占用更多内存。


    • 示例:
      • 我们要计算前一百万个数字的平方和。


        如果使用 list 来实现,方法如下。


        >>> # 创建列表对象 squares
        >>> squares = [x*x for x in range(10_000_000)]
        >>> # 计算它们的总和
        >>> sum(squares)
        333333283333335000000
        >>> squares.__sizeof__()
        81528032
        

        如上所示,list 对象占据 81528032 字节。


        我们考虑使用 generator 进行相同的 *** 作,代码如下。


        >>> # 创建 generator 对象,保存每个数的平方数
        >>> squares_gen = (x*x for x in range(10_000_000))
        >>> # 计算它们的总和
        >>> sum(squares_gen)
        333333283333335000000
        >>> squares_gen.__sizeof__()
        96
        

        使用generator与list 相比,前者的内存开销小得多,只有 96 字节。


        原因很简单,它不需要获取所有的元素。


        相反,它只需要获取各个元素在序列中的位置,创建下一个元素并呈现它,而且不必保存在内存中。


集合推导式
  • 格式:
    集合推导式基本格式:

    { expression for item in Sequence }{ expression for item in Sequence if conditional }
    
  • 示例:
    计算数字 1,2,3 的平方数:

    >>> setnew = {i**2 for i in (1,2,3)}
    >>> setnew
    {1, 4, 9}
    

    判断不是 abc 的字母并输出:

    >>> a = {x for x in 'abracadabra' if x not in 'abc'}
    >>> a
    {'d', 'r'}
    >>> type(a)
    <class 'set'>
    
函数推导式
  • 格式:
    如果推导条件或者表达式特别复杂怎么办?可以使用函数。



    把推导的条件放在函数中,既可以应对复杂的条件,又可以利用推导式的简洁写法。



    同理,如果生成推导结果的过程很复杂,也可以把逻辑放到函数中。


  • 示例:
    • 推导所有1-100之间的所有质数:2,3,5,7…

      def is_prime(num):
          if num == 1:
              return False
          for i in range(2, num):
              if (num % i) == 0:
                  return False
          else:
              return True
      
      p_nums = [i for i in range(1, 100) if is_prime(i)]
      print(p_nums)
      
    • 推导1900到2021年之间所有的年份,标记出闰年,生成结果:

      def is_run(year):
          if (year % 4) == 0:
              if (year % 100) == 0:
                  if (year % 400) == 0:
                      return True  # 整百年能被400整除的是闰年
                  else:
                      return False
              else:
                  return True  # 非整百年能被4整除的为闰年
          else:
              return False
      
      ryears = [f'闰{y}' if is_run(y) else y for y in range(1900, 2021)]
      print(ryears)
      
嵌套推导式(不推荐)
  • 示例:
    从2000年到2021年,生成每个月份:‘2000年:1月’, ‘2000年:2月’, ‘2020年:3月’, …, ‘2021年:12月’

    monthes = [f'{y}年:{m}月' for y in range(2000, 2022) for m in range(1,13) ]
    

    这里有两个for循环,类似于:

    monthes = []
    for y in range(2000, 2022):
        for m in range(1, 13):
            monthes.append(f'{y}年:{m}月')
    

    是不是下面的特别容易懂?所以两层的循环不推荐使用推导式

大数据量推导式
  • 示例:
    推导出1到100亿之间的数字的平方,代码如下:

    nums = [i * i for i in range(1, 10000000000)]
    

    但是这段代码很可能会卡死你的电脑,除非你的电脑是超级计算机。


    因为它要在内存中做100亿次计算,然后保存这100亿个数字。



    解决办法:

    • 使用生成器
      把方括号改成圆括号就可以了

      nums = (i * i for i in range(1, 10000000000))
      print(nums)
      print(next(nums))
      print(next(nums))
      print(next(nums))
      
      <generator object <genexpr> at 0x7fa0b422feb0>
      1
      4
      9
      

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/568400.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存