1. 主页
  2. Python基础到高级
  3. 解析式与迭代器

解析式与迭代器

解析式的定义

解析式是将一个可迭代对象转换成另一个可迭代的工具。在转换过程中,可以指定元素必须符合一定的条件,才能添加至新的可迭代对象中,这样每个元素都可以按需要进行转换。

解析式的用法

列表解析

列表解析返回的是列表

1). for循环常规的写法

求一个列表中所有元素的平方

>>> lst = list(range(10))
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = []
>>> for x in lst:
...     ret.append(x ** 2)
... 
>>> ret
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

使用解析式的方式,将上面的例子写下

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = [x ** 2 for x in lst]   列表解析
>>> ret
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

2). 带有判断的解析式

获取列表中所有的偶数

常规的写法

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = []
>>> for x in lst:
...     if x % 2 == 0:
...         ret.append(x)
... 
>>> ret
[0, 2, 4, 6, 8]

使用解析式的写法

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = [x for x in lst if x % 2 == 0 ]
>>> ret
[0, 2, 4, 6, 8]

3). 带有多个判断的解析式

获取列表中所有偶数,并且大于0

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = [x for x in lst if x % 2 == 0 if x > 0]
>>> ret
[2, 4, 6, 8]

获取列表中所有偶数,并且大于0,小于5

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = [x for x in lst if x % 2 == 0 if x > 0 if x < 5]
>>> ret
[2, 4]

4). 使用逻辑运算的解析式

获取列表中所有偶数,并且大于0,小于5

>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ret = [x for x in lst if x > 0 and x < 5 and x % 2 == 0]
>>> ret
[2, 4]

带多个if判断的语句,都是可以转化为调教的逻辑运算,所以一般来说,不会带多个if语句

5). 多个for的解析式

常规写法

>>> ret = []
>>> for x in range(2):
...     for y in range(2,4):
...         ret.append((x,y))
... 
>>> ret
[(0, 2), (0, 3), (1, 2), (1, 3)]

解析式写法

>>> ret = [(x,y) for x in range(2) for y in range(2,4)]
>>> ret
[(0, 2), (0, 3), (1, 2), (1, 3)]
>>> for i in ret:
...     print(i)
... 
(0, 2)
(0, 3)
(1, 2)
(1, 3)

在解析式中,是可以有多个for的,就是逐一按照上面的格式增加就好了,相当于逐层嵌套for循环

6). for 和 if语句结合的解析式

常规写法

>>> ret = []
>>> for x in range(5):
...     if x > 0:
...         for y in range(5,10):
...             ret.append((x,y))
>>> for i in ret:
...     print(i)
... 
(1, 5)
(1, 6)
(1, 7)
(1, 8)
(1, 9)
(2, 5)
(2, 6)
(2, 7)
(2, 8)
(2, 9)
(3, 5)
(3, 6)
(3, 7)
(3, 8)
(3, 9)
(4, 5)
(4, 6)
(4, 7)
(4, 8)
(4, 9)

解析式写法

>>> ret = [(x,y) for x in range(5) if x > 0 for y in range(5,10)]
>>> ret
[(1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9)]
>>> for i in ret:
...     print(i)
... 
(1, 5)
(1, 6)
(1, 7)
(1, 8)
(1, 9)
(2, 5)
(2, 6)
(2, 7)
(2, 8)
(2, 9)
(3, 5)
(3, 6)
(3, 7)
(3, 8)
(3, 9)
(4, 5)
(4, 6)
(4, 7)
(4, 8)
(4, 9)

7). 偶数求平方,奇数求立方

常规写法

>>> lst = list(range(10))
>>> ret = []
>>> for x in lst:
...     if x % 2 == 0:
...         ret.append(x ** 2)
...     else:
...         ret.append(x ** 3)
... 
>>> ret
[0, 1, 4, 27, 16, 125, 36, 343, 64, 729]

解析式的写法

>>> x = 3
>>> x ** 2 if x % 2 == 0 else x ** 3   这个是一个单独的程序,可以直接运行的
27
>>> ret = [x ** 2 if x % 2 == 0 else x ** 3 for x in lst]   结合上面的程序,就能实现“偶数求平方,奇数求立方”的解析式了
>>> ret
[0, 1, 4, 27, 16, 125, 36, 343, 64, 729]

列表解析式的优势

  • 代码简洁,可读性强
  • 效率比普通迭代稍高

列表解析式,对于性能的提升是微乎其微的,可以说,列表解析式就是为了代码的简洁,因此,我们在使用列表解析式的时候,一些复杂的循环或者判断操作,尽量不要使用列表解析式,因为那边不仅不会感觉出代码的简洁易懂,反而时间长了会自己都看不懂代码输出的结果是啥了。

生成器解析式

生成解析式返回的是一个生成器

列表解析式的中括号变成小括号,就是生成器解析式

>>> g = (x ** 2 for x in range(10000))
>>> next(g)    生成器是使用next逐条取值的
0  
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9

生成器解析式的好处:

  • 当数据量大的时候,不会占用大量的内存
  • 在取值的时候,才会计算

明确需要使用下标访问元素的时候,使用列表解析,当只需要对结果迭代的时候,优先使用生成器解析。

生成器解析式和列表解析式的使用格式是完全一样的,因此上面列表解析式的列举的所有例子,对于生成器解析同样适用

集合解析式

集合解析式返回的是一个集合

定义解析的时候,使用大括号定义,那么就是一个集合解析式了

>>> ret = {x for x in range(10)}
>>> ret
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> type(ret)
<class 'set'>

集合解析式和列表解析式的使用格式是完全一样的,因此上面列表解析式的列举的所有例子,对于集合解析同样适用

字典解析式

字典解析式返回的是一个字典

字典解析式的定义,也是使用大括号的,只不过是使用冒号来使用key->value的数据类型的

>>> ret = {str(x):x for x in range(10)}
>>> ret
{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

也是和列表解析式的表现形式一样的

我们要如何帮助您?

发表回复

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