解析式

解析式

列表解析

列表解析式是将一个列表(实际上适用于任何可迭代对象(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]: lst
Out[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]: lst
Out[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]: lst
Out[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]: lst
Out[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]: lst
Out[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 0
inc 1
inc 2
Out[39]: [1, 2, 3]

In [42]: g =  (inc(x) for x in range(3))

In [43]: next(g)
inc 0
Out[43]: 1

In [44]: next(g)
inc 1
Out[44]: 2

In [45]: next(g)
inc 2
Out[45]: 3
  • 使用生成器解析式时一点next的元素超出则报StopIteration的异常。

  • 生成器解析式只能一步步的向后而不能任意跳转。

  • 在列表解析中的元素是可以查看的而生成器只能通过next进行查看元素。

集合解析

  • 集合解析把列表解析的中括号变成大括号,返回集合。

  • 集合解析拥有集合的特性即:集合解析中的元素没有重复值、集合的元素必须是可哈希的否则报TypeError异常。

In [3]: s = {x for x in [2,3,4,5,3,4,2,7,8]}

In [4]: s
Out[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]: set
Out[15]: {'0': 5, '1': 5, '2': 5, '3': 5, '4': 5}
原文地址:https://www.cnblogs.com/cuchadanfan/p/5926072.html