2013-07-19 45 views
3

我有四個數組,比如A,B,C和D,它們的大小相同,但我想刪除它們中的所有0。如果A有一個零,B,C和D也有一個,在同一個位置。所以我想遍歷A的元素:一次刪除多個數組中的給定值的所有出現

for n in range(NumElements): 
    if A[n]==0: 
     A.pop(n) 
     B.pop(n) 
     C.pop(n) 
     D.pop(n) 

當然,這是不行的,因爲從陣列彈出0降低它們的大小,所以我最終試圖訪問A [包含numElements-1 ],現在A只有NumElements-m長。我知道我應該使用數組副本,但數組很長,我想保持低內存消耗,因爲我在Java虛擬機中工作(不要問:(((()。另外,我想的方法是有效的,但最重要的可讀性(此代碼必須通過Python的文盲像我這樣保持下去,所以我需要親吻)。謝謝,

deltaquattro

回答

4

如果他們都在同一個地方零,則環比指數反向並從每個列表中刪除該指數:

for i in reversed(range(NumElements)): 
    if not A[i]: 
     del A[i], B[i], C[i], D[i] 

通過遍歷反向列表,您保留指數穩定(只有元素過去當前索引已被刪除,僅收縮列表尾部)。既然你不是使用返回值list.pop()(無論如何你得到的是0 s吧?),你也可以直接在列表索引上使用del

這裏我用reversed(range(NumElements))代替計算更費勁range(NumElements - 1, -1, -1);它同樣高效,但更具可讀性。 reversed() function返回一個迭代器,非常有效地處理反轉的數字序列。在Python 2中,你可以做同樣的xrange()

for i in reversed(xrange(NumElements)): 

演示:

>>> A = [1, 2, 0, 4, 5, 0] 
>>> B = [2, 4, 0, 10, 9, 0] 
>>> C = [5, 3, 0, 10, 8, 0] 
>>> D = [10, 3, 0, 1, 34, 0] 
>>> for i in reversed(range(NumElements)): 
...  if not A[i]: 
...   del A[i], B[i], C[i], D[i] 
... 
>>> A, B, C, D 
([1, 2, 4, 5], [2, 4, 10, 9], [5, 3, 10, 8], [10, 3, 1, 34]) 
+0

+1,很好的一個,我忘記了:: - 1,使用比python更多的C#在工作:) –

+1

@RomanPekar:我不再創建一個新的列表;在這種情況下,我更喜歡'反轉(range())'。 –

+0

是啊,我知道了,對我來說這是一個很好的餘數 –

2

我覺得你可以做。水木清華這樣的,我不知道它是否夠Python的

A = [1, 2, 4, 0] 
B = [6, 0, 4, 3, 9] 
C = [12, 5, 32, 0, 90] 

for row in [A, B, C]: 
    for i, v in enumerate(row): 
     if v == 0: del row[i] 

,或者,如果你確定的零指標在所有名單等。

for i in range(len(A) - 1, -1, -1): 
    if A[i] == 0: 
     for row in [A, B, C]: 
      del row[i] 
+0

不錯!但是,我不明白爲什麼第一種形式可行。我猜這個'enumerate'函數會創建一個「靜態」索引列表,從0到'NumElements-1'。所以,假設我至少刪除了一個元素,當我嘗試訪問'A [NumElements-1]'時,我會得到一個錯誤。這不正確嗎? – DeltaIV

+0

以及我剛剛發現,第一個不能正常工作多於一個0,對不起。你可以使用'for i,v in reverse(list(enumerate(A))):',但是範圍更好的解決方案是更好的 –

2

只是從另一端工作!

for n in range(NumElements-1,-1,-1): 
    if A[n]==0: 
     A.pop(n) 
     B.pop(n) 
     C.pop(n) 
     D.pop(n) 
1

看看我的其他答案List accessing in Python。您可以遍歷列表A並將索引0存儲在臨時列表中,然後彈出它們。

5
a,b,c,d = [filter(lambda i: i != 0, l) for l in [a,b,c,d]] 

過濾每個列表中刪除那些不爲0

編輯元素,

只是爲了解釋發生了什麼

過濾器通過將函數應用於列表中的所有內容來獲取表達式並「過濾」列表,所有不返回True的內容。

LAMBDA是一個短手的功能

所以

a = [1,2,3,4,5,6,7,8] 

def is_even(x): 
    return x % 2 == 0 
filter(is_even, a) 
+0

非常緊湊!我不認爲我會去解決這個問題,因爲我不知道這些'filter'和'lambda'指令,mantainers可能更少。但它仍然令人印象深刻!顯示Python的強大功能。 – DeltaIV

+0

好的!現在我明白了。非常好,謝謝! – DeltaIV

1

這可能是一個黑客,但它的簡單和它的作品

>>> a = [1,2,3] 
>>> b = [1,10,99] 
>>> c = [1,87,22] 
>>> d = [] 
>>> d.extend([a,b,c]) 
>>> to_remove = 1 
>>> [i.remove(to_remove) for i in d] 
>>> d 
[[2, 3], [10, 99], [87, 22]] 

注意,這將刪除所有標記元素至於在開始時不僅僅是返回零,我認爲這對你來說是好的,因爲你說你想刪除所有的零。

+0

這不會刪除標記爲'to_remove'的所有元素,它只會刪除第一個元素。試試'a = [1,1,2,3]; b = [1,1,2,3];例如,c = [1,1,2,3]'。 – DSM

相關問題