2016-07-19 7 views
1

Ich bin neu in Python und Linux und Programmierung im Allgemeinen, tut mir leid für Noob-Fragen.Entfernen von Elementen aus der Liste (for-Schleife), aber bekommt einen Indexfehler wenn nicht genannt list.copy()

ich eine Liste der CIFS-Aktien haben, wie unten,

['Type', 'Sharename', 'Comment'] 

[['Disk', '3tb', ''], ['Disk', 'c$', 'Default share']] 

Ich möchte alle Anteile entfernen, die unter einen Kommentar gleichen wie in der Liste haben,

['Remote Admin', 'Default share', 'Remote IPC'] 

Ich schrieb die unter Stück Code, der ziemlich gut funktioniert, aber ich muss list = list.copy() anrufen. Es scheint, ich verpasse hier etwas. Ist das der richtige Weg, oder gibt es einen besseren Weg für das gleiche und es entzieht sich mir?



for skip in self.skip_shares_disc: 
    # print("Skip: " + skip) 
    for share in all_shares: 
     all_shares = all_shares.copy() 
     # print(" share[2]: " + share[2] + "drive: " + share[1]) 
     if str(share[2]).upper() == str(skip).upper(): 
      all_shares = all_shares.copy() 
      # print("  share[2]: " + share[2] + "drive: " + share[1]) 
      all_shares.remove(share) 
      all_shares = all_shares.copy() 
+1

Sie müssen die Kopie vor der 'for'-Schleife erstellen und die Kopie iterieren. In der for-Schleife müssen Sie Elemente aus der ursprünglichen Liste entfernen. – Frodon

+0

Im Allgemeinen sollten Sie nichts ändern, über das Sie gerade iterieren. Iterieren Sie stattdessen die Liste, erstellen Sie eine Liste der zu entfernenden Bezeichner und durchlaufen Sie dann die Liste * this *, indem Sie Elemente aus der Liste "all_shares" entfernen. – jedwards

+0

Mögliches Duplikat von [Elemente aus einer Liste entfernen, während in Python iteriert wird] (http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python) –

Antwort

2

Sie tun kontinuierlich all_shares.copy(), weil Sie die Liste modifizieren, während über sie iterieren. Dieser Patch verhindert, dass sich die for-Schleife mit der Listenmutation ändert; was normalerweise nicht wünschenswert ist.

Sie können jedoch alle copy durch Iterieren über eine Scheibe/Kopie der Liste löschen:

for share in all_shares[:] 

Dies ist nur eine Kopie der Liste einmal macht, im Gegensatz zwei Kopien bei jeder Iteration zu machen.

+0

Welche, nicht zufälligerweise kopiert auch die Liste. (Aber zumindest tust du es mal anstatt * n * mal) – jedwards

+2

Kopiert die Liste einmal, nicht bei jeder Iteration –

+0

habe ich nicht schnell genug bearbeitet, um sie zu fangen, aber einverstanden! – jedwards

0

Python verwendet zum Teil Konzepte aus der funktionalen Programmierung. Wenn Sie eine Liste von Dingen erstellen, die Sie behalten möchten, und diese an den Kontext zurückgeben, in dem Sie sie verwenden möchten, müssen Sie nichts löschen und Sie müssen list.copy() nicht mehrmals aufrufen.

0

Es gibt mehrere Möglichkeiten, dies zu tun. Die Pythonic ist eine Liste Verständnis zu verwenden ...

special_comments = ['Remote Admin', 'Default share', 'Remote IPC'] 
filtered_shares = [x for x in all_shares if x not in special_comments] 

Dies baut eine neue Liste nur die Elemente aus der ursprünglichen Liste zu halten, die Sie behalten möchten. Dies ist ein Beispiel für eine filter-, die Sie tatsächlich den Filter Stichwort Sie verwenden könnte ...

special_comments = ['Remote Admin', 'Default share', 'Remote IPC'] 
def condition(x): 
    return x not in special_comments 

filtered_shares = filter(condition, all_shares) 

In diesem Fall müssen Sie in der ursprünglichen Liste übergeben Sie filtern möchten, und eine Funktion, die wird return true/false für jedes Element der Liste (True, um es zu behalten, False, um es zu entfernen). Sie können es in einer Zeile tun, um eine Lambda-Anweisung ...

filtered_shares = filter(lambda x: x not in special_comments, all_shares) 

wo die Lambda-Funktion mit dem def func_name(args) Format definiert.