python list有關remove的問題


在python 中進行一次簡單的列表循環,當用到remove時出現了一個很有趣的現象,

代碼如下:

1 a=range(30)
2 for i in a :
3     if i%4!=0:
4         a.remove(i)

這段代碼是在a里取i 當i不能夠整除4 的時候,a就在自己里面刪除這個時候的i 值,最后輸出的a的結果應該是[0,4,8,12,16,20,24,28],結果真的是這樣嗎? 

1 a=range(30)
2 for i in a :
3     if i%4!=0:
4         a.remove(i)
5         
6 a
7 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

這個時候出現的結果完全不一樣,2,6,10這些根本不對,那么為什么啊?那么這里就得說一下for in和remove了,

For in 是對下標進行操作,而remove是對值進行操作

當你執行第一個的時候,a 里面的第一個數是0 現在不符合規則,然后跳過,進行下一個循環,第二個數是1, 符合規則,把a里的1刪除,現在a的表成了

[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]然該第二個了,因為for in是按照下標取值的,那么第二個就成了3而不是2,這個時候就會把2跳過,以后的類似,而remove是對值進行操作,那么你i傳到下面什么值,它就會刪除什么值。

那么怎么該解決這樣的問題呢??下面我列出了幾種解決的辦法,當然方法也不限於這幾種,代碼如下:

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # Time    : 2017-06-25 18:04
 4 # Author  : MrFiona
 5 # File    : summary_func.py
 6 # Software: PyCharm Community Edition
 7 
 8 import time
 9 
10 # TODO 4、list的remove的多次操作
11 
12 # TODO 第一種處理方法
13 def list_remove_func_1():
14     test_remove = [652, 34, 652, 652, 418, 0, 440, 220, 652, 49, 336, 493, 510, 255, 652, 652, [1, 2], 652, 652]
15     # TODO 用來標記移除的滿足條件的數據的個數
16     remove_num = 0
17     for index in range(len(test_remove) + 1):
18         if remove_num:
19             # TODO 因為移除remove_num了個數據,所以test_remove數據已經減少了相應數量
20             index -= (remove_num)
21         try:
22             # print 'index:\t', index, test_remove[index]
23             if 652 == test_remove[index]:
24                 n = test_remove[index]
25                 test_remove.remove(n)
26                 remove_num += 1
27                 # print 'remove index [ %d ]\tvalue: [ %d ]' % (index, test_remove[index])
28         # TODO 因為循環次數開始已經確定為len(test_remove),隨着不斷的移除數據,test_remove長度在減少,所以當捕捉到
29         # TODO 的IndexError的時候處理已經完成
30         except IndexError:
31             print test_remove
32 
33 
34 # TODO 第二種處理方法
35 def list_remove_func_2():
36     test_remove = [652, 34, 652, 652, 418, 0, 440, 220, 652, 49, 336, 493, 510, 255, 652, 652, [1, 2], 652, 652]
37     # TODO 使用列表表達式來完成,速度增加了五六倍
38     test_remove = [ ele for ele in test_remove if ele != 652 ]
39     # TODO 改成元祖表達式又會比列表表達式快兩倍
40     test_remove = ( ele for ele in test_remove if ele != 652 )
41     print test_remove
42 
43 
44 # TODO 第三種處理方法
45 def list_remove_func_3():
46     test_remove = [652, 34, 652, 652, 418, 0, 440, 220, 652, 49, 336, 493, 510, 255, 652, 652, [1, 2], 652, 652]
47     # TODO 移動次數比正常的移動次數相等,因為是在不停的檢測是否還有待移除的數據,有酒移除第一個被發現的符合的數據,否則ValueError退出
48     time_count = 0
49     try:
50         while 1:
51             test_remove.remove(652)
52             time_count += 1
53     except ValueError:
54         pass
55     print time_count
56 
57 """
58     TODO Summary:
59     以移除列表1000000次為准以下幾種方法所耗時間對比:
60         1、list_remove_func_2中用元祖來處理:1.5452-----最快的方法
61         2、list_remove_func_2中用列表來處理:3.2566-----僅次於元祖的方法
62         3、list_remove_func_3方法:5.6115-----比較慢的方法
63         4、list_remove_func_1方法:12.6582-----最慢的方法
64 """

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM