首页 > 代码库 > 解析式
解析式
解析式
列表解析
列表解析式是将一个列表(实际上适用于任何可迭代对象(iterable))转换成另一个列表的工具。在转换过程中,可以指定元素必须符合一定的条件,才能添加至新的列表中,这样每个元素都可以按需要进行转换。
列表解析返回的是列表, 列表的内容是表达式执行的结果
列表解析的精髓就在第一个的for循环,所以第一个必须是for循环语句
解析式速度更快
代码更简洁
可读性
实际使用
列表解析的一般形式和其等价形式
[expr for item in itratorable] ==>ret = []for item in itratorable ret.append(item)
实际使用举例:
In [2]: [ x ** 0.5 for x in range(5)]Out[2]: [0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0]In [8]: lst = []In [9]: for x in range(5): ...: lst.append(x ** 0.5)In [10]: lstOut[10]: [0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0]
带if语句的列表解析
[expr for item in iterable if cond] =>ret = []for item in iterable: if cond: ret.append(expr)
实际使用举例:
In [11]: [ x ** 0.5 for x in range(10) if x % 2 == 0]Out[11]: [0.0, 1.4142135623730951, 2.0, 2.449489742783178, 2.8284271247461903]In [12]: lst = []In [13]: for i in range(10): ....: if i % 2 == 0: ....: lst.append(i ** 0.5) In [14]: lstOut[14]: [0.0, 1.4142135623730951, 2.0, 2.449489742783178, 2.8284271247461903]
带两个if语句的使用:
[expr for item in iterable if cond1 if cond2] =>ret = []for item in iterable: if cond1: if cond2: ret.append(expr)
实际使用举例:
In [15]: [ x for x in range(20) if x % 2 ==1 if x < 10 ]Out[15]: [1, 3, 5, 7, 9]In [16]: lst = []In [17]: for x in range(20): ....: if x % 2 ==1: ....: if x < 10: ....: lst.append(x) In [18]: lstOut[18]: [1, 3, 5, 7, 9]
两个for语句的列表解析
[expr for item1 in iterable1 for item2 in iterable2] =>ret = []for item1 in iterable1: for item2 in iterable2: ret.append(expr)
实际使用举例:
In [19]: [(x,y) for x in range(3) for y in range(2)]Out[19]: [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]In [20]: lst = []In [25]: for x in range(3): ....: for y in range(2): ....: lst.append((x,y)) ....: In [26]: lstOut[26]: [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
在上面的使用中我们可以看到只要第一个是for语句剩下的语句可以是一个或多个if语句也可以是一个或多个for语句。总之合理的使用列表解析能够很好的提高代码的可读性,同时也能提高性能。
In [27]: [(x,y) for x in range(3) if x % 2 == 1 for y in range(2)]Out[27]: [(1, 0), (1, 1)]In [28]: lst = []In [29]: for x in range(3): ....: if x % 2 == 1: ....: for y in range(2): ....: lst.append((x,y)) ....: In [30]: lstOut[30]: [(1, 0), (1, 1)]
生成器解析
对生成器解析来说,只需要简单的把中括号换成小括号就可以了,而生成器解析式是按需计算的或者说延迟计算或者叫惰性求值。它和列表解析的语法很像,但是在大数据量处理时,生成器表达式的优势就体现出来了,因为它的内存使用方式更好,效率更高,它并不创建一个列表,只是返回一个生成器。当然,列表解析并不会被遗弃。
(expr for iter_var in iterable) (expr for iter_var in iterable if cond_expr)
举例:
In [37]: def inc(x): ....: print(‘inc {0}‘.format(x)) ....: return x+1 ....: In [38]: (inc(x) for x in range(3))Out[38]: <generator object <genexpr> at 0x7fc804c5e7d8>In [39]: [inc(x) for x in range(3)]inc 0inc 1inc 2Out[39]: [1, 2, 3]In [42]: g = (inc(x) for x in range(3))In [43]: next(g)inc 0Out[43]: 1In [44]: next(g)inc 1Out[44]: 2In [45]: next(g)inc 2Out[45]: 3
使用生成器解析式时一点next的元素超出则报StopIteration的异常。
生成器解析式只能一步步的向后而不能任意跳转。
在列表解析中的元素是可以查看的而生成器只能通过next进行查看元素。
集合解析
集合解析把列表解析的中括号变成大括号,返回集合。
集合解析拥有集合的特性即:集合解析中的元素没有重复值、集合的元素必须是可哈希的否则报TypeError异常。
In [3]: s = {x for x in [2,3,4,5,3,4,2,7,8]}In [4]: sOut[4]: {2, 3, 4, 5, 7, 8}
字典解析
字典解析也是使用大括号包围,并且需要两个表达式,一个生成key, 一个生成value 两个表达式之间使用冒号分割,返回结果是字典。
key是可hash的。
相同的key之间后面的值会覆盖前面值。
In [12]: { str(x):y for x in range(5) for y in range(6)}Out[12]: {‘0‘: 5, ‘1‘: 5, ‘2‘: 5, ‘3‘: 5, ‘4‘: 5}In [13]: set = {}In [14]: for x in range(5): ....: for y in range(6): ....: set[str(x)]=y ....: In [15]: setOut[15]: {‘0‘: 5, ‘1‘: 5, ‘2‘: 5, ‘3‘: 5, ‘4‘: 5}
解析式