一、range ()、map()、filter()、 dict.items()在python2.7返回列表,而在3.x中返回迭代器。当然迭代器大多数都是比较好的选择,更加pythonic,但是也有缺点,就是只能遍历一次、遍历一次之后,迭代器中就没有值了,这是一个坑点
二、闭包与lambda
>>> def create_multipliers(): ... return [lambda x:i*x for i in range(5)] ... >>> for multiplier in create_multipliers(): ... print multiplier(2) ...8,8,8,8
create_multipliers函数的返回值时一个列表,列表的每一个元素都是一个函数 -- 将输入参数x乘以一个倍数i的函数。预期的结果时0,2,4,6,8. 但结果是5个8,意外不意外。
由于出现这个陷阱的时候经常使用了lambda,所以可能会认为是lambda的问题,但lambda表示不愿意背这个锅。问题的本质在与python中的属性查找规则,LEGB(local,enclousing,global,bulitin),在上面的例子中,i就是在闭包作用域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询得到的。
解决办法也很简单
方法一、变闭包作用域为局部作用域。
>>> def create_multipliers(): ... return [lambda x, i = i:i*x for i in range(5)] ...# 将闭包函数的i变量改成了函数的局部变量,故而先找local
方法二、改为生成器
>>> def create_multipliers():
for i in range(5):
yield lambda x:i*x
三、循环过程中删除列表中的元素
因为没删除一下,后一个元素会自动前移一位,导致下一次循环时成为了漏网之鱼。