2014-02-22 15 views
2

我有一個列表,其中一些項目應該移動到一個單獨的列表中(通過比較函數)。那些元素是純粹的字典。問題是我應該如何遍歷這樣的列表。python list.iteritems replacement

當迭代最簡單的方法,for element in mylist,那麼我不知道元素的索引。列表中沒有.iteritems()方法,在這裏可能很有用。所以我試過使用for index in range(len(mylist)):,這對python來說似乎過於複雜,並且[2]不能滿足我,因爲range(len())在開始時計算一次,如果在迭代過程中從列表中移除一個元素,我會得到IndexError: list index out of range

最後,我的問題是 - 我應該如何遍歷python列表,以便能夠從列表中刪除元素(使用比較函數並將它們放在另一個列表中)?

+0

那麼,你想結束與原始列表缺少一些元素,幷包含這些元素的新列表中刪除? –

+0

@RicardoCárdenes正好 – ducin

回答

1

與刪除舊項目相比,創建新列表確實不是什麼問題。同樣,迭代兩次是非常小的性能影響,可能受其他因素影響。除非你有一個很好的理由不這樣做,通過剖析你的代碼的支持下,我建議迭代兩次,並建立兩個新的列表:

from itertools import ifilter, ifilterfalse 

l1 = list(ifilter(condition, l)) 
l2 = list(ifilterfalse(condition, l)) 

可以切片分配新的列表中的一個內容爲原來,如果你想:

l[:] = l1 

如果你絕對相信你想要一個1通解決方案,而你絕對肯定要修改代替原來的列表,而不是創建副本,下面避免從列表中間ping pop ping的二次性能命中:

j = 0 
l2 = [] 
for i in range(len(l)): 
    if condition(l[i]): 
     l[j] = l[i] 
     j += 1 
    else: 
     l2.append(l[i]) 
del l[j:] 

我們將列表中的每個元素直接移動到其最終位置,而不會浪費時間移動不需要移位的元素。如果我們想要,我們可以使用for item in l,它可能會更快一些,但是當算法涉及修改我們正在迭代的東西時,我更喜歡顯式索引。

0

你可以做到這一點,但可能是一行太多。

new_list1 = [x for x in old_list if your_comparator(x)] 
new_list2 = [x for x in old_list if x not in new_list1] 
+0

您正在創建兩個新列表並重復兩次。我正在尋找一種解決方案來迭代一次,並將元素移動到另一個列表中(例如'l2.append(l1.pop(ind))') – ducin

+0

我只是想引用@alKids解決方案。它並沒有變得更清潔。 – Martol1ni

1

我寧願不碰原始列表,做作爲@ Martol1ni,但要做到這一點的地方,也不是個辦法由取下元件的影響將是向後遍歷:

for i in reversed(range(len()): 
    # do the filtering... 

這隻會影響你已經測試過的元素的索引/已

刪除
1

沒有試過,但尚未..我給它一個快速射擊:

new_list = [old.pop(i) for i, x in reversed(list(enumerate(old))) if comparator(x)] 
+0

離開10分鐘,很快就會回來 – aIKid

+0

'reversed'只在序列上工作(其中'enumerate'對象不是) –

+1

使用'reversed(list(enumerate(old)))'你很好走。非常棒的解決方案+1。 – Martol1ni

1

可以使用枚舉功能,使列表的臨時副本:

for i, value in enumerate(old_list[:]): 
    # i == index 
    # value == dictionary 
    # you can safely remove from old_list because we are iterating over copy 
1

嘗試過濾命令,你可以用它覆蓋原始列表太多,如果你不需要它。

def cmp(i): #Comparator function returning a boolean for a given item 
    ... 

# mylist is the initial list 
mylist = filter(cmp, mylist) 

mylist現在是適合項目的生成器。如果您需要多次使用它,您可以使用list(mylist)

相關問題