迭代器、推导式、函数式编程学习笔记
1、迭代器简介
Python中很多对象都是迭代器,例如列表、元组、字符串、文件、映射、集合。
所有可迭代的类必须实现__iter__()函数,得到迭代器对象,通常返回自身(即自身就是迭代器对象);
所有的迭代器类都实现了next()函数,当然迭代器类也需要实现__iter__()函数;3.0中是__next__()函数。
2、迭代器常见用法
用法1: for 变量 in 可迭代对象
用法2:if 变量 in 可迭代对象
用法3(较少使用):变量 = iter(可迭代对象),然后循环iter.next()得到每个值,直到StopIteration异常出现。
如果想重新循环,没有回到开头的函数,可以重新得到迭代器变量,例如:it = iter(mylist) it2 = iter(it)
3、列表推导式的三种形式
基本形式: [结果表达式 for 变量 in 可迭代对象] 其中结果表达式包含循环变量
例如:[x**2 for x in range(10)]
扩展形式(增加条件):[结果表达式 for 变量 in 可迭代对象 if 条件表达式] 其中条件表达式对循环变量进行检查
例如:[x**2 for x in range(10) if x > 10]
扩展形式(多重循环): [结果表达式 for 变量 in 可迭代对象 for 变量2 in 可迭代对象2 ]
多重循环中还可以包含 if 条件表达式,对前一循环变量等进行过滤判断。
例如:[(x,y) for x in range(10) for y in range(10, 20)]
[max(x,y) for x in range(10) for y in range(10, 20)]
[max(x,y) for x in range(10) for y in range(10, 20) for z in range(20, 30)]
4、map/reduce/filter
map(function, 可迭代对象): 对可迭代对象的每一个元素,代入单参数的函数,得到的结果依次放入列表,最后得到列表。
reduce(function, 可迭代对象 [,可选的初始值]):从可迭代对象中先取两个元素,代入这个双参数的函数,得到一个结果值,然后再取出下一个值,将结果值和下一个值传入函数,再将结果与下一个值进行计算,最后得到一个列表。如果指定了可选的初始值,则第一次从可迭代对象中只取一个元素,将初始值和第一个元素代入函数。
举例: map(x**2 for x in [1,3,5]) 等效于 [x**2 for x in [1,3,5]]
map(string.lower, ['4A', 'dF']) 得到 ['4a', 'df'])
map/reduce/filter 常与lambda函数式结合起来用。
5、lambda 匿名函数
格式: lambda 变量列表: 单一表达式
例如: f = lambda x: x**2 assert( f(2) == 4 ) map(f, [3, 5])
也可直接: map(lambda x: x**2, [3, 5])
两个参数的例子: reduce(lambda x,y: x+y, [1, 3, 5])
6、lambda 递归函数
f = lambda n: n > 2 and f(n-1)+f(n-2) or 1
map(f, range(1,10))
得到:[1, 1, 2, 3, 5, 8, 13, 21, 34]
提示1:表达式中可以有函数变量名
提示2:通过 and 和 or 表达条件和多语句的效果
7、三元表达式
从lambda 递归函数顺带说明三元表达式: A if B else C ,等效于C++的 “B ? A : C”
8、简单生成器表达式
如果元素很多,才用列表会一次性加载所有元素,此时可以使用生成器表达式,即将中括号[]改为小括号()。
例如 [ x**2 for x in range(10000) ] 会一次性分配10000个元素的一个列表,而“ x**2 for x in range(10000) ”则只是一个表达式,此时并没有分配元素空间。
例如 for v in (x**2 for x in range(10000))
传入函数中时不需要加两个小括号,例如 sum(x**2 for x in range(10000))