2012-04-02 54 views
2

我有兩個列表:從兩個同步列表中刪除相同位置(索引)處的項目?

l1 = ['#', '1', '#', '!'] 
l2 = ['S', 'T', 'K', 'M'] 

如果在L1以「#」我想刪除它,並消除任何是在L2相同的位置。 這是我曾嘗試(在其他幾件事情):

for i in range(len(li[j])): 
    for k in range(len(l2[n])): 
     if j == "#": 
      li.remove([j][i]) 
      l2.remove([n][k]) 

但抱怨說,J是不可定義。 我想要的結果看起來是這樣的:

l1 = ['1', '!'] 
l2 = ['T', 'M'] 

我將是提出寶貴意見!

+0

你在哪裏設置'j'?什麼? – 2012-04-02 10:35:38

+0

'li.remove'它應該是'l1',你的循環變量是'i','k'沒有'j',因此'j'沒有被定義 – avasal 2012-04-02 10:36:04

回答

1

下面是一個簡單,易於理解的方法:

a = ["#", "1", "#", "2", "3", "#"] 
b = ["a", "b", "c", "d", "e", "f"] 

a,b = zip(*[[a[i], b[i]] for i in range(len(a)) if a[i]!="#"]) 
print a 
print b 

個人而言,我覺得它更simplier理解和更有效(讀:「更快」)比@jamylak提出的方法。

輸出:

>>> 
('1', '2', '3') 
('b', 'd', 'e') 
+0

我不會說這更容易理解比我的方法。您對每個使用的變量重複調用,而我的方法使用內置方法,因此每個變量只需使用一次。名字,例如。過濾器似乎使任何有python經驗的人都清楚這個方法。 – jamylak 2012-04-02 11:52:34

+0

@jamylak我是一個Python新手,在我看來,壓縮它兩次需要比使用簡單的生成器更多的處理能力。現在看來我可能是錯的,因爲內置函數比一段python代碼更快。 – bezmax 2012-04-02 11:58:17

+0

當然,雖然python並不總是關於速度。有時我爲了可讀性犧牲速度,只是爲了讓代碼看起來更好。如果我使用itertools中的所有方法,我可以將zips轉換爲生成器,並且運行速度會更快,但它會涉及再次將數據轉換爲列表,這不值得爲此示例發佈。 – jamylak 2012-04-02 12:02:51

0

由於您總是在兩個列表中訪問相同的索引,所以一個循環就足夠了,但是當列表長度不一樣時,您需要小心。

而且從列表中刪除,同時遍歷它是容易出錯的,下面的解決方案存儲在清除列表所有指數,並從兩個列表中的第二去刪除索引:

l1 = ['#', '1', '#', '!']  
l2 = ['S', 'T', 'K', 'M'] 
remove = [] 
for i in range(len(l1) - 1): 
    if l1[i] == '#': 
     remove.insert(0, i) 

for i in remove: 
    l1.pop(i) 
    l2.pop(i) 

for i in l1: 
    print i 
for i in l2: 
    print i 
6
>>> l1 = ['#', '1', '#', '!'] 
>>> l2 = ['S', 'T', 'K', 'M'] 

>>> l1,l2 = zip(*((x,y) for x,y in zip(l1,l2) if x!='#')) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 

使用filter

>>> l1,l2 = zip(*filter(lambda x: '#' not in x,zip(l1,l2))) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 

使用itertools

>>> from itertools import compress 
>>> l1,l2 = zip(*compress(zip(l1,l2),(x!='#' for x in l1))) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 
相關問題