1、使用场景#####
现在有一个list,其中存储有我们想要的元素和我们想要删除的元素,如何实现一边遍历列表一边删除满足条件的元素。
例:######
list_demo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
我想要一边遍历列表,一边将所有元素删除。
2、遇到问题#####
开始我使用了最容易想到的方法就是:
for item in list_demo:
item.remove(item)
但是输出结果却是这样的:
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。
C:\Users\foolf>python
Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:24:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> list_demo = [1,2,3,4,5,6,7,8,9,10]
>>> for item in list_demo:
... list_demo.remove(item)
...
>>>
>>> list_demo
[2, 4, 6, 8, 10]
>>>
从上面输出结果可以看出来只是删除了1、3、4、5、7、9。好象是每删除一个就跳过了一个。
3、解决问题#####
我简单画图分析了一下。
------------------------------
|1 | 2 | 3 | 4 | 5 |....| 10 |
-------------------------------
(只是个人见解)######
当遍历第一个元素时,删除了下标为0的元素,当遍历下标为1的元素时,后面的元素会向前移动一个位置,就是元素2移动到了原来元素1的位置,但是此时已经准备删除下标为1的元素,这样就将元素2跳过去了,以此类推,所有偶数元素都没有被删除。
方法一:
使用从后向前删除就不会有这样的情况了。
for temp in range(len(list_demo)-1, -1, -1):
list_demo.pop(temp)
运行结果如下:
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。
C:\Users\foolf>python
Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:24:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> list_demo = [1,2,3,4,5,6,7,8,9,10]
>>> for temp in range(len(list_demo)-1,-1,-1):
... list_demo.pop(temp)
...
10
9
8
7
6
5
4
3
2
1
>>>
这样就可以将所有元素边遍历边删除。
方法二:
先使用深拷贝获取一份列表的拷贝,然后遍历原来的列表。
new_list = list_demo[:]
for temp in new_list:
list_demo.remove(temp)
运行结果如下:
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。
C:\Users\foolf>python
Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:24:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> list_demo = [1,2,3,4,5,6,7,8,9,10]
>>> new_list = list_demo[:]
>>> for temp in new_list:
... list_demo.remove(temp)
...
>>> list_demo
[]
>>>
这种方法有一定的代价,如果列表很大,使用拷贝,将会将列表读取到内存中,大列表会很占内存空间,所以如果数据量大不建议使用这种方法。
END