## 一、三元表达式

``````x = 10
y = 20

print(f"x if x > y else y: {x if x > y else y}")
x if x > y else y: 20``````

## 二、列表推导式

``````[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]

res=[]
for item1 in iterable1:
if condition1:
for item2 in iterable2:
if condition2
...
for itemN in iterableN:
if conditionN:
res.append(expression)
print(F"[i for i in range(10)]: {[i for i in range(10)]}")

print(F"[i**2 for i in range(10)]: {[i**2 for i in range(10)]}")``````

[i for i in range(10)]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[i**2 for i in range(10)]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

## 三、字典生成式

``print({i: i**2 for i in range(10)})``

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

``````keys = ['name', 'age', 'gender']
values = ['nick', 19, 'male']

res = zip(keys, values)
print(F"zip(keys,values): {zip(keys,values)}")

info_dict = {k: v for k, v in res}
print(f"info_dict: {info_dict}")
``````

zip(keys,values): <zip object at 0x11074c088>
info_dict: {'name': 'nick', 'age': 19, 'sex': 'male'}

``````info_dict = {'name': 'nick', 'age': 19, 'gender': 'male'}
print(f"info_dict.keys(): {info_dict.keys()}")
print(f"info_dict.values(): {info_dict.values()}")

res = zip(info_dict.keys(), info_dict.values())
print(F"zip(keys,values): {zip(info_dict.keys(),info_dict.values())}")

info_dict = {k: v for k, v in res}
print(f"info_dict: {info_dict}")
info_dict.keys(): dict_keys(['name', 'age', 'gender'])
``````

info_dict.values(): dict_values(['nick', 19, 'male'])
zip(keys,values): <zip object at 0x1105cefc8>
info_dict: {'name': 'nick', 'age': 19, 'gender': 'male'}

## 四、生成器

### 一、yield关键字

yield的英文单词意思是生产，在函数中但凡出现yield关键字，再调用函数，就不会继续执行函数体代码，而是会返回一个值。

``````def func():
print(1)
yield
print(2)
yield

g = func()
print(g)``````

<generator object func at 0x10ddb6b48>

``````def func():
print('from func 1')
yield 'a'
print('from func 2')
yield 'b'

g = func()
print(F"g.__iter__ == g: {g.__iter__() == g}")

res1 = g.__next__()
print(f"res1: {res1}")

res2 = next(g)
print(f"res2: {res2}")

# next(g)  # StopIteration``````

g.__iter__ == g: True
from func 1
res1: a
from func 2
res2: b

``````def func():
print('from func 1')
yield 'a'
print('from func 2')
yield 'b'

g = func()
for i in g:
print(i)

print(f"list(func()): {list(func())}")
``````

from func 1
a
from func 2
b
from func 1
from func 2
list(func()): ['a', 'b']

#### 1.1 yield+return??

``````def i_wanna_return():
yield 'a'
yield 'b'
return None
yield 'c'

for i in i_wanna_return():
print(i)``````

a
b

#### 1.2 迭代器套迭代器

``````def sub_generator():
yield 1
yield 2
for i in range(3):
yield i

for i in sub_generator():
print(i)``````

1
2
0
1
2

``````def sub_generator():
yield 1
yield 2
yield from range(3)

for i in sub_generator():
print(i)
``````

1
2
0
1
2

### 二、协同程序

• 彼此间有不同的局部变量、指令指针，但仍共享全局变量；
• 可以方便地挂起、恢复，并且有多个入口点和出口点；
• 多个协同程序间表现为协作运行，如A的运行过程中需要B的结果才能继续执行。

#### 2.1 send(value):

send是除next外另一个恢复生成器的方法。Python2.5+中，yield语句变成了yield表达式，这意味着yield现在可以有一个值，而这个值就是在生成器的send方法被调用从而恢复执行时，调用send方法的参数。

``````def h():
print('--start--')
first = yield 5  # 等待接收 Fighting! 值
print('1', first)
second = yield 12  # 等待接收 hahaha! 值
print('2', second)
yield 13
print('--end--')

g = h()
first = next(g)  # m 获取了yield 5 的参数值 5
# (yield 5)表达式被赋予了'Fighting!',  d 获取了yield 12 的参数值12
second = g.send('Fighting!')
third = g.send('hahaha!')  # (yield 12)表达式被赋予了'hahaha!'
print(f'--over--')
print(f"first:{first}, second:{second}, third:{third}")
``````

--start--
1 Fighting!
2 hahaha!
--over--
first:5, second:12, third:13

• 调用send传入非None值前，生成器必须处于挂起状态，否则将抛出异常。不过，未启动的生成器仍可以使用None作为参数调用send。
• 如果使用next恢复生成器，yield表达式的值将是None。

#### 2.2 close()

``````def repeater():
n = 0
while True:
n = (yield n)

r = repeater()
r.close()
print(next(r))  # StopIteration``````

#### 2.3 throw(type, value=None, traceback=None)

``````def close(self):
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError("generator ignored GeneratorExit") # Other exceptions are not caught``````

### 三、自定义range()方法

``````def my_range(start, stop, step=1):
while start < stop:
yield start
start += 1

g = my_range(0, 3)
print(f"list(g): {list(g)}")
``````

list(g): [0, 1, 2]

### 四、总结

yield:

1. 提供一种自定义迭代器的方式
2. yield可以暂停住函数，并提供当前的返回值

yield和return:

1. 相同点：两者都是在函数内部使用，都可以返回值，并且返回值没有类型和个数的限制
2. 不同点：return只能返回一次之；yield可以返回多次值

### 五、生成器表达式

• 把列表推导式的[]换成()就是生成器表达式
• 优点：省内存，一次只产生一个值在内存中
``````t = (i for i in range(10))
print(t)
print(f"next(t): {next(t)}")``````

<generator object at 0x1101c4888>
next(t): 0

#### 5.1 生成器表达式和列表推导式

``````# 生成器表达式
with open('52.txt', 'r', encoding='utf8') as f:
nums = [len(line) for line in f]

print(max(nums))``````

1

``````# 列表推导式
with open('52.txt','r',encoding='utf8') as f:
nums = (len(line) for line in f)

print(max(nums)) # ValueError: I/O operation on closed file.``````

0条评论