Python 之推导式

导读:本篇文章讲解 Python 之推导式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

语法

分类

列表推导式

集合推导式

字典推导式


        推导式(comprehensions),又称解析式,是 Python 中常见的语法糖。推导式可以从一个数据序列构建另一个新的数据序列,常用于数据处理场景。

语法

表达式 for 迭代变量 in 可迭代对象 [if 条件表达式]

其中 if 条件判断根据需要,可有可无。

        推导式的核心为 for 循环。根据返回对象的不同,推导式可区分为列表推导式,字典推导式,结合推导式等。不同推导式在语法上基本一致。

 

分类

列表推导式

        列表推导式(list comprehension)是一种简化的 for 循环创建列表,为最常见的推导式。

例 1

>>> l = []
>>> for i in range(5):
        l.append(i)
>>> l
[0, 1, 2, 3, 4]

        上述 for 循环转换为列表推导式则为:

>>> l = [l for l in range(5)]
>>> l
[0, 1, 2, 3, 4]

        可见,与单纯 for 循环相比,作为语法糖,列表推导式简化了代码,返回新的列表。

 

        列表推导式也可以应用于相对复杂的场景:

例 2

>>> evens = [i for i in range(10) if i % 2 == 0]
>>> evens
[0, 2, 4, 6, 8]

 

 例 3

>>> l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> l = [l[i][i] for i in range(len(l))]
>>> l
[1, 5, 9]

 

例 4

>>> l = [lambda x: x* i for i in range(3)]
>>> type(l[0]), "---", l[0])
<class 'function'> --- <function <listcomp>.<lambda> at 0x7f9e19ab00>
>>> l[1](2)
4

 

        更可以实现复杂的嵌套循环:

例 5 

>>> matrix = [
    [1, 2, 3], 
    [4, 5, 6], 
    [7, 8, 9]
]
>>> l = [i for row in matrix for i in row]
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9]

         若以 for 循环来表示,则为:

>>> matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

>>> l = []

>>> for row in matrix:
        for i in row:
            l.append(i)
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9]

 

例 6

>>> l = [x**y+z for x in range(2) for y in range(3) for z in range(4)]
>>> l
[1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]

 

例 7

>>> names = [['Billy', 'Jefferson', 'Andrew', 'Wesley', 'Joe'],
         ['Steven', 'Alice', 'Jennifer', 'Eva', 'Sherry']]
>>> print([name for i in names for name in i if name.count('e') >= 2])
['Jefferson', 'Wesley', 'Steven', 'Jennifer']

 

例 8 

>>> matrix = [
    [1, 2, 3], 
    [4, 5, 6], 
    [7, 8, 9]
]
>>> print([[row[i] for row in matrix] for i in range(3)])
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

         该例嵌套了内外循环,等价于

>>> l = []
>>> matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
>>> for i in range(3):
        temp = []
        for row in matrix:
            temp.append(row[i])
        l.append(temp)
>>> print(l)

        通过上述示例,可见:

  • 列表推导式遍历顺序为自右而左,先遍历 for 后的可迭代对象,然后根据 for 前的表达式进行运算,最终生成新的列表。
  • 如果有 if 条件语句,for 遍历后即进行条件判断。
  • 如果有多个 for 循环,则最终的对象个数为多个 for 循环的笛卡尔积。
  • 嵌套的列表推导式,与嵌套 for 循环的原理相同。

 

        毋庸置疑,列表推导式以一行代码之简,挽多行代码之繁。但正如一个硬币有其两面, 多个表达式和可迭代对象融入一行代码,不可避免带来可读性降低的问题,有时甚至晦涩难懂,且出错后难以排查。且随着一行代码的延长,甚至超过代码规范的长度(一般为80个字符),更使得代码的理解变得困难。因此,适可而止是为上策。

 

        有时,面对长长的推导式,可采用断行的方式予以处理,以便理解。 

例 2

evens = [
    i 
    for i in range(10) 
    if i % 2 == 0
]

 

 例 7

[
    name 
    for i in names 
    for name in i 
    if name.count('e') >= 2
]

 

        如果把列表推导式的 [] 替换为 (),则变为生成器(generator )表达式

例 8

>>> g = ( i for i in range(6))
>>> g
<generator object <genexpr> at 0x7f7f201e00>
>>> list(g)
[0, 1, 2, 3, 4, 5]
>>> list(g)
[]

        生成器推导式与列表推导式的区别在于:

  • 生成器表达式一次遍历,随后清空生成器对象,因此比列表推导式速度更快,占用的内存也更少。
  • 返回值不同。列表推导式返回新列表。生成器表达式返回生成器对象。

 

        生成器表达式的返回结果可以根据需要转化为列表或元组,也可以 for 或 __next__() 方法或内置函数 next() 遍历:

例 9

>>> g = (i for i in '上帝与你同在')
>>> for i in g:
        print(i)
    
上
帝
与
你
同
在

>>> g = (i for i in '上帝与你同在')
>>> next(g)
'上'
>>> next(g)
'帝'
>>> g.__next__()
'与'
>>> g.__next__()
'你'

集合推导式

        集合推导式跟列表推导式非常相似,唯一区别在于用 {} 代替 []

例 10

>>> S = {x for x in range(10) if x % 2 == 0}
>>> S
{0, 2, 4, 6, 8}

例 11

>>> names = ['Billy', 'Jefferson', 'Andrew', 'Wesley', 'Joe']
>>> S = {name[0] for name in names}
>>> S
{'A', 'W', 'B', 'J'}

 

字典推导式

        字典推导式为列表推导式思想的延续,语法差不多,只不过返回的是字典而已。

例 12

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> print({d[k]: k for k in d})
{1: 'a', 2: 'b', 3: 'c'}

例 13

>>> d = {'a': 4, 'B': 3, 'c': 2, 'D':1}
>>> print({i.lower(): d.get(i.lower(), 0) + d.get(i.upper(), 0) for i in d.keys()})
{'a': 4, 'b': 3, 'c': 2, 'd': 1}


注:

1、关于语法糖,请参见:Python 之语法糖手到擒来的快感Python 之推导式https://blog.csdn.net/iprobobo/article/details/1235688392、关于列表,请参见:Python 序列之三言两语序列是具有先后关系的一组元素…Python 之推导式https://blog.csdn.net/iprobobo/article/details/122542937

3、关于集合,请参见:Python 集合之 abc集合之合集Python 之推导式https://blog.csdn.net/iprobobo/article/details/122511498

4、关于字典,请参见:Python 字典之演义映射无处不在,键值对无处不在。Python 之推导式https://blog.csdn.net/iprobobo/article/details/122668767

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/106918.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!