Skip to main content
 首页 » 编程设计

快速掌握Python推导式

2022年07月19日132lvdongjie

推导式(comprehension)是一种从一个或多个迭代器创建Python数据结构的紧凑方式。推导式能够用更少的代码实现循环和条件测试组合的冗长语法。使用推导式通常被认为是Python老手的标志,也就是说更Python。

list 推导式

下面构建list,包括1到5的整数,代码如下:

number_list = [] 
number_list.append(1) 
number_list.append(2) 
number_list.append(3) 
number_list.append(4) 
number_list.append(5) 
number_list 

输出结果:
[1, 2, 3, 4, 5]

也可以是哟个迭代器和range()函数:

number_list = [] 
for number in range(1, 6): 
    number_list.append(number) 
 
number_list 

或者直接在list中报告range():

number_list = list(range(1, 6) 
number_list 

所有这些方法都可行且结果相同。但更Python方式是使用list推导式,其简单语法形式为:

[ expression for item in iterable ]

使用list推导式实现同样功能:

number_list = [number for number in range(1,6)] 
number_list 

在第一行中,第一个number变量是给list产生值,即把循环的结果存入number_list中。第二个number是循环体的一部分。为了说明第一个number是表达式,我们可以修改上面的示例:

number_list = [number-1 for number in range(1,6)] 
number_list 

输出结果为:

[0, 1, 2, 3, 4]

list推导式把循环放在方括号内。这个推导式示例与前面实现相比并没有太多简化,但list推导式可以包括条件表达式,语法如下:

[ expression for item in iterable if condition ]

下面示例仅生成1~5中的奇数:

a_list = [number for number in range(1,6) if number % 2 == 1] 
a_list 

输出结果:

[1, 3, 5]

实现同样功能,如果使用传统方法:

a_list = [] 
for number in range(1,6): 
    if number % 2 == 1: 
    a_list.append(number) 
 
a_list 

最后我们看推导式如何实现嵌套循环,首先看原始方式:

rows = range(1,4) 
cols = range(1,3) 
for row in rows: 
    for col in cols: 
    print(row, col) 

输出结果:

1 1
1 2
2 1
2 2
3 1
3 2

使用推导式实现:

rows = range(1,4) 
cols = range(1,3) 
cells = [(row, col) for row in rows for col in cols] 
for cell in cells: 
    print(cell) 

输出结果:

(1, 1)
(1, 2)
(2, 1)
(2, 2)
(3, 1)
(3, 2)

如果需要解包直接输出值,利用下面代码实现与传统方式输出一致:

for row, col in cells: 
    print(row, col) 

字典推导式

字典也支持推导式,最简单语法如下:

{ key_expression : value_expression for expression in iterable }

与list类似,字典推导式也可以有if子句,下面看示例:

word = ' letters' 
letter_counts = {letter: word.count(letter) for letter in word} 
 
letter_counts 

输出结果:

{' l' : 1, ' e' : 2, ' t' : 2, ' r' : 1, ' s' : 1}

上面示例为了统计字母出现数量,但循环却要遍历所有字母,其中t、e遍历了两次。可以稍微修改下提升性能:

word = ' letters' 
letter_counts = {letter: word.count(letter) for letter in set(word)} 
letter_counts 

{' t' : 2, ' l' : 1, ' e' : 2, ' r' : 1, ' s' : 1}

输出结果一致,但顺序不同,主要是set是无序的。

set推导式

估计你也想到了,set也支持推导致。最简单的语法如下:

{ expression for expression in iterable }

最完整的示例(包括if条件子句):

a_set = {number for number in range(1,6) if number % 3 == 1} 
a_set 

输出结果:

{1, 4}

生成器推导式

Tuple(元组)没有推导式。你可能会想直接修改方括号为圆括号不就行了吧。我们通过示例看看:

number_thing = (number for number in range(1, 6)) 
type(number_thing) 

输出结果:

<class ' generator' >

我们看到其类型是生成器,它是给数据提供迭代器一种方式。

迭代上述输出变量:

for number in number_thing: 
    print(number) 

输出:

1
2
3
4
5

当然也可以通过list包装迭代器变量,就像使用了list推导式:

number_list = list(number_thing) 
number_list 
 

输出结果:

[1, 2, 3, 4, 5]

生成器仅能运行一次。列表、集合、字符串和字典都存在于内存中,但生成器是动态创建值,并通过迭代器一次输出一个值,然后则不记得它们,所以你不能重新启动或备份生成器。请看示例:

try_again = list(number_thing) 
try_again 

输出为:
[]


本文参考链接:https://blog.csdn.net/neweastsun/article/details/125036665