【Python 高级特性】推导式:一行更比三行强,用更少的代码写出更高的效率
Hi 朋友们,我会用一系列文章展示 Python 高级特性,这篇文章是系列的第一篇。
Python 高级特性是 Python 中相对于基础写法更加高效的特性。如果你刚刚学完 Python 的基础语法,那么我非常推荐你学习这些高级特性。它有一点学习成本,但能极大提升代码效率,原本需要一天才能完成的代码,如果你熟练使用高级特性,可以压缩到一小时完成。
今天我想要分享的内容是推导式。推导式是一种高效创建列表、字典、集合或其他可迭代对象的方式,常规方法需要 3 行才能完成的功能,使用推导式仅需要 1 行。
你会在下面的例子中看到,如何构造推导式和推导式的优势。
现在让我们开始吧!
列表推导式
基础使用
第一个例子很简单,仅仅是复制了一个列表。
1
2
3
4
5
6
nums = [0,1,2,3,4,5]
my_list = []
for i in nums:
my_list.append(i)
print(my_list)
让我们看看常规方法是怎么做的,首先创建一个新列表,然后使用 for
循环遍历原有列表中的每个元素,再将每个元素都添加到新列表中。
下面是列表推导式的写法。
1
2
my_list = [i for i in nums]
print(my_list)
看,原本需要三行才能完成的功能,通过列表推导式,一行就够了。
现在让我们来看一下列表推导式的构造。两边的方括号意味着我们正在构造一个列表,最前面的 i
是要放在新列表中的元素,后面的 for i in nums
告诉我们,i
是 nums
中的每个元素。
这是一个非常简单的列表推导式,我希望这个例子能让你看到列表推导式很好写,也很有用。
现在让我们看另一个稍微复杂一点的例子。
加入操作
现在,我们需要创建一个新列表,存储原有列表中每个数字的平方。
1
2
3
4
5
6
nums = [0,1,2,3,4,5]
my_list = []
for i in nums:
my_list.append(i**2)
print(my_list)
与上一个例子相比,只改动了一个地方。添加到新列表中的不再是 i
,变成了 i**2
。
如果使用列表推导式,也只需要改动一个地方。
1
2
my_list = [i**2 for i in nums]
print(my_list)
将最前面的 i
改为 i**2
,意味着需要放在列表中的是 i
的平方。后面的 for i in nums
与之前的例子一样,告诉我们 i
是 nums
中的每个元素。
让我们继续,看看下一个更复杂一点的例子。
加入条件
现在,我只想将列表中偶数平方,而不是每个元素都平方。
1
2
3
4
5
6
7
nums = [0,1,2,3,4,5]
my_list = []
for i in nums:
if i % 2 == 0:
my_list.append(i**2)
print(my_list)
在上一个例子的基础上, for
循环内添加了if
语句,对 nums
中的每个元素判断是否为偶数。
以下是使用列表推导式的写法。
1
2
my_list = [i**2 for i in nums if i % 2 == 0]
print(my_list)
和常规写法的顺序一致,都是在 for
循环后添加了 if
语句用于判断。
如果我想更复杂一点点,在推导式中加入 else
语句,那么顺序就会有所改变,比如下面的代码。
1
my_list = [i**2 if i % 2 == 0 else i**3 for i in nums]
先是 if...else
结构,然后才是 for
语句。顺序刚好与上面先 for
后 if
相反,对于新手来说并不友好。所以,在你能够熟练使用列表推导式之前,我不建议在列表推导式中加入 else
语句。
接下来,是一个更复杂的列表推导式。
嵌套 loop
现在我想要一个元组组成的列表。这个元组的两个元素分别来自两个列表。一个列表是 ['a', 'b', 'c']
,另一个是 [1, 2, 3]
。也就是说,我希望得到 [(a1), (a2), (a3), (b1), (b2), (b3), (c1), (c2), (c3)]
这样的列表。
1
2
3
4
5
6
7
8
letters = ['a', 'b', 'c']
nums = [1, 2, 3]
my_list = []
for i in letters:
for j in nums:
my_list.append((i, j))
print(my_list)
常规写法使用了两个 for
循环嵌套,在列表推导式中也是一样。
1
2
my_list = [(i, j) for i in letters for j in nums]
print(my_list)
列表推导式中的两个 for
顺序与常规语句一样。前面的 for
是外循环,里面的 for
是内循环。
除了列表,字典和集合也可以使用推导式,它们的语法基本一致,只有细微的差别。让我们来看看。
字典推导
以下语句展示了如何 for 循环两个列表来创建一个字典。
1
2
3
4
5
6
7
letters = ['a', 'b', 'c']
nums = [1, 2, 3]
my_dict = {}
for i, j in zip(letters, nums):
my_dict[i] = j
zip
函数的功能是将两个列表中的元素一一对应起来,返回一个元组构成的可迭代对象。在这个例子中,zip
函数返回的是 ('a', 1), ('b', 2), ('c', 3)
。
上述代码先创建一个空字典,然后使用 for
循环遍历每个元组,将元组的第一个元素作为 key,第二个元素作为 value,添加到空字典中。
现在我将使用推导式进行改写。
1
2
my_dict = {i:j for i, j in zip(letters, nums)}
集合推导
集合是一种相对字典和列表没那么常见的数据类型,特点是无序且不重复。当你想要去除一个列表中的重复元素时,就会用到集合。 集合推导式的写法与列表推导式非常相似,下面的语句根据一个列表新建了一个集合。
1
2
3
4
5
6
l = [1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 9]
my_set = set()
for i in l:
my_set.add(i)
首先创建一个空集合,然后使用 for 循环遍历 l,将每个元素添加到 my_set 中。
现在我将使用推导式进行改写。
1
2
my_set = {i for i in l}
与列表推导唯一的不同仅在于将方括号换成了花括号。
最后
通过这篇内容,你会发现,列表推导式、字典推导式、集合推导式的写法写起来非常简单,作用却非常大。现在你可以浏览你的代码并用这些推导式来替换一些臃肿的 for 循环,这一定会让你的代码更上一层楼。 如果你还有其他的问题,欢迎在评论区留言,我会尽快回复。 如果你觉得这篇文章对你有帮助,欢迎点赞分享。也欢迎关注我的频道,我会持续更新 Python 相关的内容。感谢你的阅读。