翼度科技»论坛 编程开发 python 查看内容

Python推导式 - 最全用法

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
1、 Pythonic - 很Python

写一段代码生成1到100之间的数字的平方的列表,答案是:
  1. 1, 4, 9, 16...
复制代码
如果你这样写,你就不Pythonic了:
解释 
  1. nums = []
  2. for i in range(1, 101):
  3.     nums.append(i*i)
  4. print(nums)
复制代码
正确的写法是使用Python的推导式:
  1. nums = [i*i for i in range(1, 101)] 
复制代码
2、 带条件的推导式

生成一个列表,包含1到100之间是3的倍数的数字的方法:
  1. 9, 36, 81...
复制代码
代码:
  1. nums = [i * i for i in range(1, 101) if i % 3 == 0]
复制代码
3、 带条件的表达式

生成一个列表,如果是3的倍数就用平方,否则就用是数字本身:
  1. 1, 2, 9, 4, 5, 36...
复制代码
代码:
  1. nums = [i * i if i % 3 == 0 else i for i in range(1, 101)]
复制代码
  
结合上面的3个例子,来看一下推导式总结:

  • 推导式从一个可枚举数据(列表,元组,集合,字典等)推导出一个列表。也可以推导出生成器,集合或字典。
  • 推导式可以加推导条件,只对符合条件的元素推导
  • 要推导出的元素使用表达式生成,可以用if else生成不同元素
  1. [表达式 if 表达式条件 else 分支 for i in 序列 if 推导条件]
复制代码
4、 使用函数

如果推导条件或者表达式特别复杂怎么办?可以使用函数。
推导所有1-100之间的所有质数:2,3,5,7...
解释  
  1. def is_prime(num):
  2.     if num == 1:
  3.         return False
  4.     for i in range(2, num):
  5.         if (num % i) == 0:
  6.             return False
  7.     else:
  8.         return True
  9. p_nums = [i for i in range(1, 100) if is_prime(i)]
  10. print(p_nums)
复制代码
  
把推导的条件放在函数中,既可以应对复杂的条件,又可以利用推导式的简洁写法。
同理,如果生成推导结果的过程很复杂,也可以把逻辑放到函数中。
推导1900到2021年之间所有的年份,标记出闰年,生成结果:
  1. 1900, 1901, 1902, 1903, '闰1904'
复制代码
代码:
解释 
  1. def is_run(year):
  2.     if (year % 4) == 0:
  3.         if (year % 100) == 0:
  4.             if (year % 400) == 0:
  5.                 return True  # 整百年能被400整除的是闰年
  6.             else:
  7.                 return False
  8.         else:
  9.             return True  # 非整百年能被4整除的为闰年
  10.     else:
  11.         return False
  12. ryears = [f'闰{y}' if is_run(y) else y for y in range(1900, 2021)]
  13. print(ryears)
复制代码
  
5、 嵌套表达式 - 不推荐使用

从2000年到2021年,生成每个月份:'2000年:1月', '2000年:2月', '2020年:3月', ..., '2021年:12月'
  1. monthes = [f'{y}年:{m}月' for y in range(2000, 2022) for m in range(1,13) ]
复制代码
这里有两个for循环,类似于:
解释 
  1. monthes = []
  2. for y in range(2000, 2022):
  3.     for m in range(1, 13):
  4.         monthes.append(f'{y}年:{m}月')
复制代码
  
是不是下面的特别容易懂?所以两层的循环不推荐使用推导式,哈哈。
那我为什么还要讲?你会碰到有人这么写,知道它的存在还是有点必要的。
6、 推导巨大的列表 - 不要这么干!

推导出1到100亿之间的数字的平方,代码如下:
  1. nums = [i * i for i in range(1, 10000000000)]
复制代码
但是这段代码很可能会卡死你的电脑,除非你的电脑是超级计算机。因为它要在内存中做100亿次计算,然后保存这100亿个数字。
7、 使用生成器

这种情况下,我们应该使用推导生成器,用法很简单:

  • 把方括号改成圆括号就可以了
解释  
  1. nums = (i * i for i in range(1, 10000000000))
  2. print(nums)
  3. print(next(nums))
  4. print(next(nums))
  5. print(next(nums))
复制代码
打印出来是一个生成器:
解释  
  1. <generator object <genexpr> at 0x7fa0b422feb0>
  2. 1
  3. 4
  4. 9
复制代码
这是一个生成器,它不会一次性生成100亿个数字,只有调用next()的时候,它才会生成一个新的,返回给你。也就是说,同一个时间,只保存一个数字。
8、 推导字典

推导字典的方式和推导列表很相似,只不过:

  • 使用大括号
  • 使用键值对
推导一个包含数字和数字平方组成的字典,结果是这样的:
  1. {1: 1, 2: 4, 3: 9, ..., 100: 10000}
复制代码
代码:
  1. nums_dict = {n: n * n for n in range(1, 101)}
  2. print(nums_dict)
复制代码
反过来,平方在前面,数字在后面:
  1. nums_dict = {n * n:n for n in range(1, 101)}
  2. print(nums_dict)
复制代码
给下面的字典按照分数排序:
  1. {'麦叔':59, '张三':87, 'FGA':78, '石石':100, '莫名':90}
复制代码
排序结果:
  1. {'石石': 100, '莫名': 90, '张三': 87, 'FGA': 78, '麦叔': 59}
复制代码
代码:
  1. scores = {'麦叔': 59, '张三': 87, 'FGA': 78, '石石': 100, '莫名': 90}
  2. sored_scores = {item[0]: item[1] for item in sorted(scores.items(), key=lambda item: item[1], reverse=True)}
  3. print(sored_scores)
复制代码

  • 先把字典scores变成一个元组列表:scores.items()
  • 用sorted函数给元组列表排序:sorted(scores.items(), key=lambda item:item[1], reverse=True)
  • 排序过程用lambda指定使用元组的第二列排序:key=lambda item:item[1]。默认是是第一列。
  • 指定倒着排序,也就是分数高的在前面:reverse=True
  • 使用推导式,把排好序的元组列表,生成一个新的排好序的字典:{item[0]:item[1] for item in ... }
9 推导集合Set

推导集合的方式和列表是一样的,区别在于:

  • 使用大括号,类似于推导字典,但它是单个元素,而不是键值对。
  • 集合会自动过滤掉重复的元素。
下面的名字列表,去掉前后空格后去掉重复的名字:
  1. [ '麦叔', '张三', ' 麦叔 ', 'FGA ', '张小三', 'FGA', '石石',' 莫名','莫名' ]
复制代码
推导结果:
  1. {'石石', 'FGA', '张小三', '莫名', '张三', '麦叔'}
复制代码
代码:
  1. names = [ '麦叔', '张三', ' 麦叔 ', 'FGA ', '张小三', 'FGA', '石石',' 莫名','莫名' ]
  2. new_names = {n.strip() for n in names}
  3. print(new_names)
复制代码
                                  Top                                                  收藏                                                  关注                                                  评论
来源:https://www.cnblogs.com/smiler/p/18132453
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具