作家
登录

程序员老司机都要错的Python陷阱与缺陷列表

作者: 来源: 2017-10-12 11:04:09 阅读 我要评论

  1. >>> a[1] 
  2.  
  3. [10] 
  4.  
  5. >>> a 
  6.  
  7. [[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]] 

我猜,这应当不是你预期的结不雅吧,究其原因,照样因为python中list是可变对象,上述的写法大年夜家都指向的同一个可变对象,精确的姿势

  1. >>> a = [[] for _ in xrange(10)] 
  2.  
  3. >>> a[0].append(10) 
  4.  
  5. >>> a 
  6.  
  7. [[10], [], [], [], [], [], [], [], [], []] 

第五,在拜访列表的时刻,修改列表

列表(list)在python中应用异常广泛,当然经常会在拜访列表的时刻增长或者删除一些元素。比如,下面这个函数,试图删掉落列表中为3的倍数的元素:

  1. >>> def modify_lst(lst): 
  2.  
  3. ... for idx, elem in enumerate(lst): 
  4.  
  5. ... if elem % 3 == 0: 
  6.  
  7. ... del lst[idx] 

测试一下,

  1. >>> lst = [1,2,3,4,5,6] 
  2.  
  3. >>> modify_lst(lst) 
  4.  
  5. >>> lst 
  6.  
  7. [1, 2, 4, 5] 

似乎没什么错,不过这只是命运运限好

  1. >>> lst = [1,2,3,6,5,4] 
  2.  
  3. >>> modify_lst(lst) 
  4.  
  5. >>> lst 
  6.  
  7. [1, 2, 6, 5, 4] 

膳绫擎的例子中,6这个元素就没有被删除。如不雅在modify_lst函数中print idx, item就可以发明端倪:lst在变短,但idx是递增的,所以在膳绫擎掉足的例子中,当3被删除之后,6变成了lst的第2个元素(大年夜0开端)。在C++中,如不雅遍历容器的时刻用迭代器删除元素,也会有同样的问题。

第六,闭包与lambda

这个也是老发展谈的例子,在其他说话也有类似的情况。先看一个例子:

  1. >>> def create_multipliers(): 
  2.  
  3. ... return [lambda x:i*x for i in range(5)] 
  4.  
  5. ... 
  6.  
  7. >>> for multiplier in create_multipliers(): 
  8.  
  9. ... print multiplier(2) 
  10.  
  11. ... 

因为出现这个陷阱的时刻经常应用了lambda,所以可能会认为是lambda的问题,但lambda表示不肯意背这个锅。问题的本质在与python中的属性查找规矩,LEGB(local,enclousing,global,bulitin),在膳绫擎的例子中,i就是在闭包感化域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包顶用到的变量的值,是在内部函数被调用时萌芽获得的。

解决办法也很简单,那就是变闭包感化域为局部感化域。

  1. >>> def create_multipliers(): 
  2.  
  3. ... return [lambda x, i = i:i*x for i in range(5)] 
  4.  

  5.   推荐阅读

      从开发到部署会用到的 Docker 命令

    本文的目标是懂得容器开辟在目标情况中安排的端到端流程,并列出这些操作所需的 Docker 敕令。1. 介绍全部流程包含应用代码、依附软件和设备来开辟容器映像,在开辟情况中运行和测试容器,将容器映像宣>>>详细阅读


    本文标题:程序员老司机都要错的Python陷阱与缺陷列表

    地址:http://www.17bianji.com/lsqh/37834.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)