奇技,还是正统功夫?Python推导式最全用法

奇技,还是正统功夫?Python推导式最全用法来源:麦叔编程作者:麦叔一、Pythonic – 很Python写一段代码生成1到100之间的数字的平方的列表,答案是:1,4,9,16…如

大家好,欢迎来到IT知识分享网。

来源:麦叔编程

作者:麦叔

一、Pythonic – 很Python

写一段代码生成1到100之间的数字的平方的列表,答案是:

1,4,9,16...

如果你这样写,你就不Pythonic了:

nums = [] for i in range(1,101):     nums.append(i*i) print(nums)

正确的写法是使用Python的推导式:

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

二、带条件的推导式

生成一个列表,包含1到100之间是3的倍数的数字的方法:

9,36,81...

代码:

nums = [i*i for i in range(1,101) if i%3==0]

三、带条件的表达式

生成一个列表,如果是3的倍数就用平方,否则就用是数字本身:

1,2,9,4,5,36...

代码:

nums = [i*i if i%3==0 else i for i in range(1,101)]

结合上面的3个例子,来看一下推导式总结:

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

四、使用函数

如果推导条件或者表达式特别复杂怎么办?可以使用函数。

推导所有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年之间所有的年份,标记出闰年,生成结果:

1900, 1901, 1902, 1903, '闰1904'

代码:

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,)]

但是这段代码很可能会卡死你的电脑,除非你的电脑是超级计算机。因为它要在内存中做100亿次计算,然后保存这100亿个数字。

七、使用生成器

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

  • 把方括号改成圆括号就可以了
  • nums = (i*i for i in range(1,)) print(nums) print(next(nums)) print(next(nums)) print(next(nums))

    打印出来是一个生成器:

    <generator object <genexpr> at 0x7fa0b422feb0> 1 4 9

    这是一个生成器,它不会一次性生成100亿个数字,只有调用next()的时候,它才会生成一个新的,返回给你。也就是说,同一个时间,只保存一个数字。

    八、推导字典

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

    1. 使用大括号
    2. 使用键值对

    推导一个包含数字和数字平方组成的字典,结果是这样的:

    {1: 1, 2: 4, 3: 9, ..., 100: 10000}

    代码:

    nums_dict = {n:n*n for n in range(1,101)} print(nums_dict)

    反过来,平方在前面,数字在后面:

    nums_dict = {n*n:n for n in range(1,101)} print(nums_dict)

    给下面的字典按照分数排序:

    {'麦叔':59, '张三':87, 'FGA':78, '石石':100, '莫名':90}

    排序结果:

    {'石石': 100, '莫名': 90, '张三': 87, 'FGA': 78, '麦叔': 59}

    代码:

    scores = {'麦叔':59, '张三':87, 'FGA':78, '石石':100, '莫名':90} sored_scores = {item[0]:item[1] for item in sorted(scores.items(), key=lambda item:item[1], reverse=True)} print(sored_scores)
    1. 先把字典scores变成一个元组列表:scores.items()
    2. 用sorted函数给元组列表排序:sorted(scores.items(), key=lambda item:item[1], reverse=True)
    3. 排序过程用lambda指定使用元组的第二列排序:key=lambda item:item[1]。默认是是第一列。
    4. 指定倒着排序,也就是分数高的在前面:reverse=True
    5. 使用推导式,把排好序的元组列表,生成一个新的排好序的字典:{item[0]:item[1] for item in … }

    九、推导集合Set

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

    1. 使用大括号,类似于推导字典,但它是单个元素,而不是键值对。
    2. 集合会自动过滤掉重复的元素。

    下面的名字列表,去掉前后空格后去掉重复的名字:

    [ '麦叔', '张三', ' 麦叔 ', 'FGA ', '张小三', 'FGA', '石石',' 莫名','莫名' ]

    推导结果:

    {'石石', 'FGA', '张小三', '莫名', '张三', '麦叔'}

    代码:

    names = [ '麦叔', '张三', ' 麦叔 ', 'FGA ', '张小三', 'FGA', '石石',' 莫名','莫名' ] new_names = {n.strip() for n in names} print(new_names)

    免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/75892.html

    (0)
    上一篇 2024-07-26 11:33
    下一篇 2024-07-26 13:33

    相关推荐

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注

    关注微信