<原创>关于python中的一些坑点

一、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

三、循环过程中删除列表中的元素

  因为没删除一下,后一个元素会自动前移一位,导致下一次循环时成为了漏网之鱼。

posted @ 2017-08-08 11:44  子彦  阅读(154)  评论(0编辑  收藏  举报