天问

  • Blog
  • 热修复与动态加载
  • python爬虫
  • 专栏
    • 热修复与动态加载
    • NDK开发
    • 设计模式与架构
    • React Native
  • 好文转载
    • 计算机技术
    • 投资理财
    • 摄影与拍照技巧
  • 投稿
  • 关于本站及隐私政策
  • Github
StevenQ
为今天工作,为明天投资,为未来孵化一些东西!
  1. 首页
  2. 计算机技术
  3. python
  4. 正文

python遍历删除同时修改List中的元素

2017年3月25日 1420点热度 3人点赞 2条评论

         之前没怎么接触过python,因为项目要用的python,所以开始学习python,说实话和java,c++比起来,python简单多了,但是由于是初次学习,在使用python遍历删除元素的时候遇到了一些坑,简单的记录下。

       先说下应用场景:在进行安卓Apk的so加密保护中,需要从用户输入的一个so的list列表中,首先要判断用户输入的so是否在待加密Apk中存在,当然允许用户输入大小写有误,如果不存在则将该so从用户输入的list列表中删除,如果仅仅是大小写不匹配则认为该so是存在的,即需要修正so列表,且结果要反应到用户传入的so的list中。

       因为结果要反应到用户传入的so的list中,那么很显然,我们应该对传入的list进行操作,而不能重新定一个list操作,然后返回。soLists为传入的用户输入的so列表,因为工作原因,只能贴出部分代码,代码如下:

existedSoList=[];
zipFileLists=ZipManager.getZipNameList(tempApkPath)
for file in zipFileLists:
    if file.endswith('.so'):
        soName=os.path.split(file)[-1]
        existedSoList.append(soName)
#for so in soLists[:]:
for i in range(len(soLists)-1,-1,-1):#此处使用for in range,
    flag=False
    for existedSo in existedSoList:
       if  existedSo.lower() == soLists[i].lower():
            flag=True
            soLists[i] = existedSo    #修正soLists
    if not flag:
          soLists.remove(soLists[i])#修正soLists

  在上述代码中遍历方式使用的是for in range,而不是for in形式。 因为虽然使用for in可以做到安全的遍历删除,遍历拷贝的list,操作原始的list:代码如下:

for so in soLists[:]:
flag=False
for existedSo in existedSoList:
   if  existedSo.lower() == so.lower():
        flag=True
        so = existedSo    #修正soLists
if not flag:
      soLists.remove(so)#修正soLists

但是事实上,so = existedSo这句代码起不到期待的作用,因为为了保证遍历时的安全删除采用的是遍历拷贝的list,操作原始的list(如果不这么做则不能在遍历时删除元素,不然可能导致数组下标越界的错误),所以so = existedSo这个语句不会反应到原始的传入的so的list中,也即起不到修正大小写的作用。所以采用的是for in range形式倒序遍历删除同时可以修改原list中的元素的值。 因为是直接对原list进行操作,所以为了保证遍历的时候安全删除采用了倒序遍历的形式,即通过指定range函数的参数,range函数的定义如下:

def range(start=None, stop=None, step=None)

我们知道在c++/java中我们通常这么使用for循环

for(int i=0;i<list.size();i++) //正序访问元素
for (int i=list.size()-1;i >-1;i--) // 逆序访问元素

而在python中的range函数的start参数就是起始访问下标,stop就是结束访问下标,而step则是访问的步长,该值可以为正(正序访问元素),也可以为负(逆序访问元素),但是不能为0.如:

for i in range(len(list)-1,-1,-1):

等同于c++/java中的:

for (int i=list.size()-1;i >-1;i--) // 逆序访问元素

总结:如果仅仅只是在遍历的时候安全删除元素,可以采用

1遍历拷贝的list,操作原始的list:

for so in soLists[:]:

2采用for in range 的形式倒序遍历。

for i in range(len(list)-1,-1,-1):

如果仅仅只是在遍历的时候安全删除元素,推荐第一种方式,如果不仅要保证遍历时安全删除,同时要修改原list的元素的值,那个采用第二种方式。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: python
最后更新:2017年4月15日

天问

追梦追自由,穷则独善其身,达则兼济天下

打赏 点赞
下一篇 >

文章评论

  • 马化腾

    写的不错,的确是python新手容易遇到的问题,赞一个。
    评论者头像来自Gravatar。

    2017年3月25日
    回复
    • huqi

      @马化腾 这名字太吊了,难道是腾讯的那个马化腾pony? :razz:

      2017年4月15日
      回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    COPYRIGHT © 2022 天问 ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang