生成器
生成器的例子
任何包含yield的语句的函数称之为生成器.函数会返回一个迭代器.
简单例子
#!/usr/bin/env python
def flatten(nested):
for sublist in nested:
for ele in sublist:
yield ele
nested = [[1,2],[3,4],[5]]
print list(flatten(nested))
递归生成器
def flatten_recursion(nested):
try:
for sublist in nested:
for ele in flatten_recursion(sublist):
yield ele
except TypeError:
yield nested
print list(flatten_recursion([[[1],2],3,4,[5,[6,7]],8]))
处理字符串:(检查一个字符串:将传入的对象和一个字符串拼接,看看是否产生TypeError)
def flattern_string(nested):
try:
try:
nested + ''
except TypeError:
pass
else:
raise TypeError:
for sublist in nested:
for ele in flattern_string(sublist):
yield ele
except TypeError:
yield nested
print list(flattern_string(['foo',['bar']]))
生成器推导式于跟列表推导式类似,只不过将[]改为()
eg:
(i for i in range(8))
模拟生成器
1.在函数开始处添加 result = []
2 . yield some_expression 替换为 result.append(some_expression)
3. return result
def flattern_string(nested):
reuslt = []
try:
try:
nested + ''
except TypeError:
pass
else:
raise TypeError:
for sublist in nested:
for ele in flattern_string(sublist):
result.append( ele)
except TypeError:
result.append(nested)
return result
print list(flattern_string(['foo',['bar']]))
8皇后问题
#!/usr/bin/env python
import random
# state[0]=3表示第一行皇后放在第四列
def queens(num = 8, state=()):
result = []
for pos in range(num):
if not conflict(state, pos):
if len(state) == num -1:
yield (pos,)
else:
for result in queens(num, state+(pos,)):
yield result +(pos,)
def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
#下一个皇后和前个皇后的水平距离为0或者等于垂直距离
if abs(state[i] - nextX) in (0, nextY - i):
return True
return False
def prettyprint(solution):
def line(pos, length = len(solution)):
return '.'*(pos) + "X" + '.'*(length -1 -pos)
for pos in solution:
print line(pos)
prettyprint(random.choice(list(queens(8))))