2013-10-15 14 views
0

我想從列表中刪除A.在B名單中發現的列表項這是我寫的函數:如何使用多維數組流行的Python的方式

def remove(A,B): 

    to_remove=[]; 
    for i in range(len(A)): 
     for j in range(len(B)): 
      if (B[j]==A[i]): 
       to_remove.append(i); 

    for j in range(len(to_remove)): 
     A.pop(to_remove[j]); 

這是做正常的方式它呢?儘管這樣做很好(如果錯別字,我不知道),但我認爲可能會有更多的pythonic方式來做到這一點。請建議。

+0

如果'A = [1,1,1,1,2,2,2]'和'B = [1,1,2]'做你想刪除在A或僅1每場比賽和2兩個1和1 2? – dawg

回答

2

首先,請注意,你的功能不能正常工作。試試這個:

A = [1, 2, 3] 
B = [1, 2, 3] 
remove(A, B) 

你會得到一個IndexError,因爲正確的索引中刪除每次做一個.pop()時間變化

你會毫無疑問,得到答案使用幾組建議,這是真的,如果數組元素是可哈希和可比較的好很多,但一般你可能需要的東西是這樣的:

def remove(A, B): 
    A[:] = [avalue for avalue in A if avalue not in B] 

,對於工程任何種類的數組元素(只提供它們可以比較相等),並保留原來的順序。但是這需要與len(A) * len(B)成比例的最壞情況時間。

+0

忘了想想這個。謝謝。 –

+0

@Jack_of_All_Trades,你可以像原來那樣修復它:'for i in reversed(to_remove):del A [i]'。像這樣的技巧是從最大的索引中刪除。然後刪除的其他元素保留其原始位置:-) –

2

列表comprehenstion救援:

[item for item in A if item not in B] 

然而,這將創建一個新的列表。您可以從函數返回列表。

或者,如果您沒有問題列表A失去任何重複,或有沒有重複,你可以使用set區別:

return list(set(A) - set(B)) 

一個需要注意的是,這會不會保留元素的順序在A。所以,如果你想要的元素,這不是你想要的。改用第一種方法。

+0

該解決方案不會保留'A'中的原始順序,對嗎?或者我錯了? – aga

+0

@aga哦,是的。忘了提到這一點。我會補充。 –

5

轉換Bset第一,然後創建從A使用列表理解一個新的數組:在一組

s = set(B) 
A = [item for item in A if item not in s] 

項目查找是一個O(1)操作。

如果你不想改變Aid(),則:

A[:] = [item for item in A if item not in s] 
+0

人們可以他們兩個轉換成'set'然後用'A.difference(B)' –

+0

@WayneWerner這將不保留訂單。 –

+0

正確 - 我想這取決於是否需要保存訂單。 –

2

什麼列表理解?

def remove(removeList, fromList): 
    return [x for x in fromList if x not in removeList] 

此外,爲了使生活更輕鬆,消除快,你可以從列表removeList做一套,只留下獨特的元素:

def remove(removeList, fromList): 
    removeSet = set(removeList) 
    return [x for x in fromList if x not in removeSet] 

>>> print remove([1,2,3], [1,2,3,4,5,6,7]) 
[4, 5, 6, 7] 

,當然,你可以使用內置的filter功能,雖然有人會說它是非pythonic,你應該使用列表生成器來代替。無論哪種方式,這裏是一個例子:

def remove(removeList, fromList): 
    removeSet = set(removeList) 
    return filter(lambda x : x not in removeSet, fromList) 
+1

在這裏,我們創造的每一步一個新的'set',所以這仍然是'O(N ** 2)'。 –

+1

@hcwhsa這就是爲什麼我喜歡這樣:當你回答別人的問題,somebody'll點你出一些錯誤在你自己的答案。我從來沒有想過,列表解析會做出新的'set'在這種情況下每一步,非常感謝您的評論! – aga