簡體   English   中英

Python忽略命令從列表中刪除項目

[英]Python ignoring command to remove items from list

我正在篩選大量詞典。 kept是全局列表,其中包含大約9000個字典,所有字典都具有相同的鍵。 我正在嘗試刪除所有'M_P'值大於-4.5的字典,並且其中一半以上,因此我僅為他的目的創建了一個函數。 當我檢查一下是否在以后的功能中將它們全部刪除時,仍然還有〜3000。 誰能告訴我為什么會發生這種情況,我是否可以相信這些功能將按照我的指示去做?

def removeMag():

    countMag = 0
    for mag in kept:
        if to_float(mag['M_P']) > -4.5:
            kept.remove(mag)
            countMag += 1
        else:
            continue

    print '\n'
    print ' Number of mags > -4.5 actually removed: '
    print countMag

def remove_anomalies():    
    count = 0
    count08 = 0
    count09 = 0
    count01 = 0
    countMag = 0
    countMagDim = 0
    #Want to remove Q* < 15 degrees
    for row in kept:
        #to_float(kept(row))
        #Q* greater than 15
        if to_float(row['Q*']) < 15.00:
            kept.remove(row)
        elif to_float(row['vel']) > 80.00:
            kept.remove(row)
        elif to_float(row['err']) >= 0.5*to_float(row['vel']):
            kept.remove(row)

        elif row['log_10_m'] == '?':
            kept.remove(row)
            #print row
            count+=1
        elif row['M_P'] == '?':
            kept.remove(row)
            countMag += 1
        elif to_float(row['M_P']) > -4.5:
            countMagDim += 1

就在這里,我正在檢查它。 ^^^

        elif to_float(row['T_j']) < -50.00 or to_float(row['T_j'] >    50.00):
        kept.remove(row)
        count01 += 1

        #make sure beg height is above end height.
        elif to_float(row['H_beg']) < to_float(row['H_end']):
            kept.remove(row)
        #make sure zenith distance is not greater than 90
        elif to_float(row['eta_p']) > 90.00:
            kept.remove(row)
        #Remove extremities hyperbolic orbits    
        elif (to_float(row['e']) > 2.00 and to_float(row['e']) == 0.00 and to_float(row['a']) == 0.00 and to_float(row['incl']) == 0.00 and to_float(row['omega']) == 0.00 and to_float(row['anode']) == 0.00 and to_float(row['alp_g']) == 0.00 and to_float(row['del_g']) == 0.00 and to_float(row['lam_g']) == 0.00 and to_float(row['bet_g']) == 0.00):
            kept.remove(row)
            count08+=1
        elif to_float(row['q_per']) == 0.00:
            kept.remove(row)
            count09+=1
        elif to_float(row['q_aph']) == 0.00:
            kept.remove(row)
            count09+=1
        else: continue

    print 'Number of dicts with ? as mass value:'
    print count    

    print " Number removed with orbital elements condition: "
    print count08

    print "Number of per or aph equal to 0: "
    print count09

    print "Number of T_j anomalies: "
    print count01

    print "Number of Magnitudes removed from '?': "
    print countMag

以下輸出類似3000。

    print "Number of Magnitudes to be removed from too dim: "
    print countMagDim   
'''    
    print "\n"
    print "log mass values:"
    for row2 in kept:
        print row2['log_10_mass']
    print "\n"
'''

使用for循環進行迭代時,Python不會自動創建列表的副本,而是直接對其進行迭代。 因此,當您刪除一個元素時,循環將不會考慮更改,並且會跳過列表中的元素。

例:

>>> l = [1,2,3,4,5]
>>> for i in l: l.remove(i)
>>> l
[2, 4]

您可以使用列表索引作為速記,以在迭代之前制作列表的副本,例如:

>>> for i in l[:]: l.remove(i)
>>> l
[]

正如其他人所說,您在迭代數組時正在修改它。

一個簡單的單線是

kept = [mag for mag in kept if to_float(mag['M_P']) <= -4.5]

只需保留您感興趣的所有條目,即可替換原始列表。

計算除去的數量僅是在理解前后取len(kept)並取其差值即可。

或者,

discarded = [mag for mag in kept if to_float(mag['M_P']) > -4.5]
kept = [mag for mag in kept if to_float(mag['M_P']) <= -4.5]

拆分數組而不會丟失任何信息

您永遠不要修改for循環中要迭代的序列。 看一下您的第一個功能:

def removeMag():

    countMag = 0
    for mag in kept:
        if to_float(mag['M_P']) > -4.5:
            kept.remove(mag)
            countMag += 1

您正在呼吁remove關於kept在環。 這會導致未指定的行為,並且可能發生任何事情。 看到這個問題

解決此問題的一種簡單方法是對要保留的項目使用新列表:

mag_to_keep = []
for mag in kept:
    if float(mag['M_P']) <= -4.5:
        mag_to_keep.append(mag)

kept = mag_to_keep

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM