列表解析
简洁、高效是Python的惯有风格,
而今天所要介绍的就是如何更加优雅、快捷地创建各种序列,而使用到的语句就是十分基础的for
循环,
这种方法我们称其为列表解析(list comprehension)。
ps.虽然可以通过这种方法创建字典、元组等其他序列,但是创建出来的是一个生成器(generator)对象
(将会在后文中实践一番 >_<)
列表解析的定义
列表解析是由括号内一个或者多个
for
语句或者任意个for
、if
子语句还有一个表达式构成的
list_1 = [i for i in range(11) if i%3 != 0]
以上就是最为基础的列表解析
列表解析的使用方法
列表解析的核心语句就是
for
循环,并且可以在此基础上嵌套使用各种其他的语句,我们就来介绍一下最为基础的使用方法
基础用法
创建普通列表
list_1 = [i for i in range(6)] # list_1 = [0, 1, 2, 3, 4, 5]
# 这种创建列表的方式是不是看上去更加高大上呢?
# 那么,我们接下来想想,以前想要创建一个名为 list_1 的列表是怎么做的呢?
list_1 = [0, 1, 2, 3, 4, 5]
# 或者是这样的
list_1 = []
for i in range(6):
list_1.append(i)
# 那么接下来用列表解析的方法尝试去创建一下元组、字典、集合,看一下结果如何
tuple_1 = (i for i in range(6))
print(tuple_1, type(tuple_1)) # <generator object <genexpr> at 0x00000151178284A0> <class 'generator'>
dict_1 = {i: i**2for i in range(6)}
print(dict_1, type(dict_1)) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25} <class 'dict'>
set_1 = {i for i in range(6)}
print(set_1, type(set_1)) # {0, 1, 2, 3, 4, 5} <class 'set'>
# 我们可以使用for循环创建列表、字典、集合,但是唯独元组会生成一个生成器 <class 'generator'>
# 是不是奇怪的知识又增加了?后续有机会将继续介绍什么是生成器以及为什么列表解析加括号会出现生成器
创建特定列表
接下来我们将继续以for循环来创建列表,
但是我们将会创建一些更符合我们需求的列表
# 假设我们要把10以内的奇数都挑选出来,所以我们应该这样敲代码
list_1 = [num for num in range(11) if num%2 != 0] # [1, 3, 5, 7, 9]
# 这种创建列表的方式其实等同于这样
list_1 = []
for i in range(11):
if i%2 != 0:
list_1.append(i)
# 同样的我们还可以这样
list_2 = [i**2 for i in range(11)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
list_3 = [i**2 for i in range(11) if i %2 != 0] # [1, 9, 25, 49, 81]
# 这意味着我们可以在for循环的右边写上一些筛选条件,同时左边获得指定的值
# 接下来继续展示如何创建字典
dict_1 = {i: i**2 for i in range(11)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}
dict_2 = {i: i**2 for i in range(11) if i%2 != 0} # {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
# 异曲同工之妙,只要掌握了这种方法我们就可以更优雅创建
列表解析与函数的嵌套使用
在前文之中我们已经知道了,列表解析可以创建出自己所需要、所期望的列表了,
而接下来就必须介绍一下列表解析和函数的嵌套使用方式了。
# 先定义一个简单的函数
def test(num):
return num*2
list_1 = [test(i) for i in range(11)] # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 仔细想一下如果不用函数嵌套是不是又更简单的方法
# list_1 = [i*2 for i in range(11)] 其实就是更加方便地做法
# 那这样的话学习这个内容有什么用?
# 话可不能这么说,因为在真正地生活中我们可能需要构建一个复杂函数,同时对一个可迭代对象一直计算,那么这个列表解析不就有用武之地了?
# 再举一个例子,使用内置函数abs()
list_2 = [abs(i) for i in range(-10,10,2)] # [10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10]
# 这就是列表解析地嵌套使用
列表解析与列表解析地嵌套使用
在前文之中描述列表解析定义时就说过
列表解析是由一个表达式,一个for
循环语句,还有多个或者0个for
、if
子语句构成的
而现在我们就需要介绍一下列表解析与列表解析地嵌套问题
list_1 = [(i, x) for i in range(3) for x in range(3)] #[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 这就是嵌套地列表解析,这样地效果其实等同于这样
'''
list_1 = []
for i in range(3):
for i in range(3):
list_1.append()
'''
# 我们可以继续嵌套使用if语句像这样
list_2 = [(i,x)for i in range(10) if i%2 != 0 for x in range(5) if x%2 != 0]
# [(1, 1), (1, 3), (3, 1), (3, 3), (5, 1), (5, 3), (7, 1), (7, 3), (9, 1), (9, 3)]
# 如果出现这种的多重嵌套则效果等同于
'''
list_2 = []
for i in range(10):
if i % 2 != 0:
for x in range(5):
if x % 2 != 0:
list_2.append((i, x))
[(1, 1), (1, 3), (3, 1), (3, 3), (5, 1), (5, 3), (7, 1), (7, 3), (9, 1), (9, 3)]
'''
# 我们虽然可以这样写一个多重嵌套的列表解析,但是实际情况一般都是用不到
# 因为我们有很多功能强大的内置函数 map() enumerate() filter() zip() 以及lambda
# 这些函数有机会的话将在后续逐一介绍
题目练习
经过上文的介绍后
我们文章的结尾将会以一道比较经典的列表解析题目来进行巩固、复习
matrix = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
]
# matrix = [[x,x,x,x],[x,x,x,x],[x,x,x,x]]
# 以上是一个矩阵,在matrix这个列表中包含着3个元组,而每个元组中都含有4个元素,我们暂时称它为一个3*4的矩阵
# 现在提一个需求,使用列表解析将其更改为4*3的矩阵,也就是说将其变为包含4个元组,每个元组内含有3个元素
# 目标结构是这样的 matrix = [[x,x,x],[x,x,x],[x,x,x],[x,x,x]]
# 最开始,肯定都是懵逼的
# 好那我们退而求其次,不需要使用列表解析,仅仅使用最基础的 for 循环来构建
matrix_1 = []
for i in matrix:
for x in i:
matrix_1.append(x)
# 最开始我们只能够想到这样的作法,可这样结果是真的对吗?
# print(martix_1) [1,2,3,4,6,7,8,9,10,11,12] 这显然是一种错误的方式
# 不过没事,我们已经迈出了第一步,虽然这种方法是错误的(因为这样是遍历出matrix中的所有元素)
# 仔细观察一下,matrix的矩阵中的每个元组都有4个元素,而我们要将其更改为4*3的矩阵
# 所以思路就是,每次从元组中抽出1个元素,然后我们就可以获得3个元素(因为有3个元组嘛),而将这3个元素组合成一个新的元组,
# 重复上述思路4次,就可以得到4个元组,而每个元组内的元素就是3个
# 因此代码要这样敲
matrix_1 = []
for i in range(4): # 重复4次,每次从各个元组获得一个元素
matrix_2 = [] # 重制matrix_2
for x in matrix: # 遍历出matrix中的元组
matrix_2.append(x[i]) # 将元组中的元素添加进matrix_2中
matrix_1.append(matrix_2) # 将matrix_2添加到matrix_1中
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# 我们已经有了第一个版本的了原始代码了,那么我接下里要做的就是优化
# 优化的地方就是创建列表的过程
matrix_1 = []
for i in range(4):
matrix_1.append(x[i] for x in matrix) # x[i] for x in matrix 创建了列表,包含的是每个元组中的一个元素
matrix_1 = [[x[i] for x in matrix] for i in range(4)]
# 这就是我们的最终版本
以上就是本篇文章的全部内容,能够阅读到这里的都是条汉子!