# Python解析式

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

python的解析式具体分为以下四种：

• 列表解析式
• 生成器解析式
• 集合解析式
• 字典解析式

<!–more–>

## 列表解析式

#### 列表解析式的形式

• `[expr for e in iterator]`
```In [1]: lst = range(10)
In [2]: %%timeit
...: ret = [x ** 2 for x in lst]
...:
100000 loops, best of 3: 5.28 µs per loop
In [3]: %%timeit
...: ret = []
...: for x in lst:
...:     ret.append(x ** 2)
...:
100000 loops, best of 3: 6.09 µs per loop    # 耗时稍高```

#### 列表解析式可以和 `if` 语句一起使用

```In [4]: ret = []
In [5]: for x in lst:
...:     if x % 2 == 0:
...:         ret.append(x)    # 使用for循环
...:
In [6]: ret
Out[6]: [0, 2, 4, 6, 8]
In [7]: ret = [x for x in lst if x % 2 == 0]    # 使用列表解析式
In [8]: ret
Out[8]: [0, 2, 4, 6, 8]```

• 带多个if语句的，都可以转化为条件的逻辑运算， 所以一般来说，不会带多个if语句

```In [9]: (x, y) for x in range(0, 5) for y in range(5, 10)
File "<ipython-input-9-825e2443da8b>", line 1
(x, y) for x in range(0, 5) for y in range(5, 10)
^
SyntaxError: invalid syntax
# 说明列表解析式一定要使用中括号括起来
In [10]: [(x, y) for x in range(5) for y in range(5, 10)]
Out[10]:
[(0, 5),
(0, 6),
(0, 7),
(0, 8),
(0, 9),
(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)]
In [11]: ret = []
In [12]: for x in range(5):
...:     for y in range(5, 10):
...:         ret.append((x, y))
...:
In [13]: ret
Out[13]:
[(0, 5),
(0, 6),
(0, 7),
(0, 8),
(0, 9),
(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)]```

#### `if` 语句的特殊用法

`if``else` 必须同时存在。

```In [14]: ret = []
In [15]: for x in lst:
...:     if x % 2 == 0:
...:         ret.append(x ** 2)
...:     else:
...:         ret.append(x ** 3)
...:
In [16]: ret
Out[16]: [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]
In [17]: x = 3
# if特殊用法
In [18]: x ** 2 if x % 2 == 0 else x ** 3
Out[18]: 27
In [19]: 3 if True else 4
Out[19]: 3
# 如果采用if特殊用法配合列表解析式 x if cond else y for ...
In [20]: [x ** 2 if x % 2 == 0 else x ** 3 for x in lst]
Out[20]: [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]```

## 生成器解析式

```In [1]: range(10000)
Out[1]: range(0, 10000)
In [2]: g = (x ** 2 for x in range(100000000000))
In [3]: g
Out[3]: <generator object <genexpr> at 0x7f9f08a5f0a0>
In [4]: next(g)
Out[4]: 0
In [5]: next(g)
Out[5]: 1
In [6]: next(g)
Out[6]: 4```

• 需要用下标访问的时候，用列表解析式
• 只需要对结果迭代的时候，优先使用生成器解析式

## 集合解析式

```In [1]: lst = [2, 4, 5, 6, 3, 4, 2]
In [2]: s = {x for x in lst}
In [3]: s
Out[3]: {2, 3, 4, 5, 6}    # 可见列表解析式生成的时候会去掉重复，符合集合要求
In [4]: type(s)
Out[4]: set```

## 字典解析式

```In [1]: {str(x): x for x in range(5)}
Out[1]: {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}```