python 循环高级用法

``[expression for x in X [if condition] for y in Y [if condition] ... for n in N [if condition]]``

## 高级语法

### 1. 带有 if 语句

``````>>> L = [1, 2, 3, 4, 5, 6]
>>> L = [x for x in L if x % 2 != 0]
>>> L
[1, 3, 5]``````

### 2. 带有 for 嵌套

``````>>> [x + y for x in 'ab' for y in 'jk']
['aj', 'ak', 'bj', 'bk']``````

### 3. 既有 if 语句又有 for 嵌套

``````[ expression for x in X [if condition]
for y in Y [if condition]
...
for n in N [if condition] ]``````

``````>>> [(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]``````

``````>>> L = []
>>> for x in range(5):
...     if x % 2 == 0:
...         for y in range(5):
...             if y % 2 == 1:
...                 L.append((x, y))
>>> L
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]``````

### 4. 列表推导式生成矩阵

``````>>> M = [[1, 2, 3],
... [4, 5, 6],
... [7, 8, 9]]``````

``````>>> M = [[x, x+1, x+2] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]``````

``````>>> M = [[y for y in range(x, x+3)] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]``````

### 6. 集合推导式和字典推导式

``````>>> {x ** 2 for x in [1, 2, 2]}
{1, 4}``````

``````>>> D = {'a':1, 'b':2, 'c':3}
>>> D = {value: key for key, value in D.items()}
>>> D
{1: 'a', 2: 'b', 3: 'c'}``````

``````lix = [];
for x in range(1, 101):
lix.push(x ** 2)

``````lix = [x * x for x in range(1, 101) if x % 2 == 0]

``````lix = [x + y  for x in "abc" for y in "xyz"]

### 7.列表动态构建器

``````# 常规构建器的做法
lix = [2*x + 1 for x in range(1, 101)]
# 执行结果：[1,3,5,7,9,11,13,15,17.....]
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 常规构建器可以直接构建生成
# 但是存在问题，如果一次构建的数据量太大，会严重占用内存
# 我们在使用该列表的时候，有可能只是使用前10项
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 使用列表动态构建器
lix = (2 * x - 1 for x in range(1, 101))
# 执行结果：print (lix) --> <generator object <genexpr> at 0x7f232e462048>
next(lix)
# 执行结果：1
next(lix)
# 执行结果：3
next(lix)
# 执行结果：5
next(lix)
# 执行结果：7
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 列表动态构建器
# 和构建器基本没有区别，创建的时候列表中是没有数据的
# 必须通过next()函数来获取列表中的下一条数据
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *``````

[] 改成`()`，就创建了一个 generator：

``````>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>``````

L 和`g`的区别仅在于最外层的`[]``()``L`是一个 list，而`g`是一个 generator。

``````>>> next(g)
>>> next(g)
>>> next(g)
>>> next(g)
>>> next(g)``````

next(g) 实在是太变态了，正确的方法是使用`for`循环，因为 generator 也是可迭代对象：

``````>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
...

``````def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'``````
``````>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>``````

yield 关键字，那么这个函数就不再是一个普通函数，而是一个 generator：

``````>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>``````

return 语句或者最后一行函数语句就返回。而变成 generator 的函数，在每次调用`next()`的时候执行，遇到`yield`语句返回，再次执行时从上次返回的`yield`语句处继续执行。
.