迭代器 & 生成器

# look https://www.zhihu.com/question/20829330
# 生成器函数: 使用yield语句而不是return语句返回结果。
# yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
def gensquares(N):  
    for i in range(N):
        yield i ** 2

for item in gensquares(5):  
    print(item)
print()  
items = gensquares(5)  
print(next(items))  
print()

# 使用列表推导,将会一次产生所有结果
squares = [x**2 for x in range(5)]  
print(squares)  
print()

# 生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
# 将列表推导的中括号,替换成圆括号,就是一个生成器表达式
squares = (x**2 for x in range(5))  
# print(squares)
print(next(squares))  
# 注意前方高能!!!下面代码执行时间非常长
# sum([i for i in range(10000000000)])
result = sum(i for i in range(101))  
print(result)  
# 生成器的唯一注意事项就是:生成器只能遍历一次

map() & reduce() & filter() & sorted()

map(fun, args) 用来把函数依次作用在多个参数上,使用 list() 来计算序列并返回 list

reduce(fun, args) 用来把函数依次作用在第 n 个参数和第 n+1 个参数上,并返回一个遍历的数值

filter(fun, args) 根据 fun 返回的 bool 值来决定是否丢弃参数中第 n 个值,并返回一个 list

sorted(arg, key=key, reverse=True)

key :排序依据,eg:abs、str.lower
reverse:True 倒序排列 False 正序排列

from functools import reduce  
def return_n(n):  
    return n

def return_x_add_y(x, y):  
    return x + y

def is_odd(n):  
    return n % 2 == 1

a = [1, 2, 3, 4, 5, 6]  
r = map(return_n, a)  
# 由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list
x = list(r)  
print(x)  
add = reduce(return_x_add_y, [1, 3, 5, 7, 9])  
print(add)  
odd_list = list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))  
print(odd_list)  
sort = sorted([36, 5, -12, 9, -21])  
print(sort)  

返回函数和匿名函数

返回函数:

  • 使用函数作为一个函数的返回值(函数里面定义函数并返回子函数)
  • 子函数引用上级函数命名空间里的变量
  • 闭包函数必须返回内嵌函数
  • 在调用父函数的时候并不执行而是在调用实现函数的时候在真正执行
>>> f = fun(a,b,c)
>>> f()

类似于对象, 多个实现互不影响

def lazy_sum(*args):  
    def sum():
        result = 0
        for n in args:
            result = result + n
        return result
    return sum

ls = lazy_sum(1, 2, 3, 4, 5)  
print(ls)  
print(ls())  

匿名函数: lambda

f = lambda x, y: x * x + y  
print(f)  
print(f(5, 1))  

可以把匿名函数作为返回值:

def build(x, y):  
    return lambda: x * x + y * y
fb = build(3, 5)  
print(fb())  

python 对象作用域

class Person:  
    name = []

p1 = Person()  
p2 = Person()

p1.name.append(1)  
print(p1.name)  # [1]  
print(p2.name)  # [1]  
print(Person.name)  # [1]


class Person:  
    def __init__(self):
        self.name = []

p1 = Person()  
p2 = Person()

p1.name.append(1)  
print(p1.name)  [1]  
print(p2.name)  []