2016-06-11 12 views
0

ich nach einer Möglichkeit, jedes n-ten Element zu entfernen (lassen Sie sich das Element nennen i) in einer Liste, und auch x Anzahl der Elemente, die direkt i in der Liste sind, wenn i eine Bedingung erfüllt.Wenn Element in der Liste Bedingung erfüllt, entfernen Sie Artikel und mehr vorhergehende Artikel

Ich habe mich um List Comprehensions und Iterationen gekümmert, aber es war schwierig für einen Anfänger, eine Lösung zu finden.

Beispiel:

myList = ["you", "are", "right", "I", "am", "wrong"] 

Für jeden 3. Artikel, prüfen Sie, ob i == "wrong": Wenn ja, entfernen i und die zwei(2) Artikel vorhergehendeni.

Wirkung: Die Sequenz "I, "am", "wrong" wird aus der Liste gelöscht.

+0

Was passiert, wenn "falsch" am Anfang der Liste auftritt, oder wenn zwei "falsche" Zeichen mit weniger als zwei Zeichen auftreten? – BrenBarn

+1

Und ... denkst du, wir sind hier, um das für dich zu schreiben? – jonrsharpe

+0

@BrenBarn Danke für die Nachfrage! Das wird nie passieren - in meinem Beispiel kann man nur "rechts" und "falsch" am dritten Ort finden. Und da drei Elemente gelöscht werden, wenn die Bedingung erfüllt ist, bleibt es so. Aber für zukünftige Leser, die nicht an diese Regel gebunden sind, sollte die Reihenfolge der Liste berücksichtigt werden. – Winterflags

Antwort

1
>>> myList = ["you", "are", "right", "I", "am", "wrong"] 
>>> for i, l in enumerate(myList): 
... if l == 'wrong': 
...  myList = myList[:i-2] 
...  break 
... 
>>> myList 
['you', 'are', 'right'] 

Natürlich könnte man 2 macht eine Variable

+1

Ich glaube, dass Ihr Code nur funktioniert, wenn die Länge der Liste ein Vielfaches von 3 ist und der einzige überprüfte Wert, der 'falsch' ist, ist der ** letzte **. –

+1

Ich denke, es findet das erste Vorkommen von "falsch", das als eine Variable für eine andere Zeichenfolge angegeben werden könnte, und dann nimmt ein Stück von allem von Anfang an bis zu 2 Werte vor der "falschen" Position. Ich stimme zu, dass es nicht robust ist, aber es löst die Frage des OP. Er gab an, dass seine Liste die erforderliche Anzahl von Elementen vor dem Trigger-String hat. –

+0

Danke Joel. Ich benutze dies am Ende, weil die Syntax für mich einfacher zu verstehen war und auch mit einigen Modifikationen in mein "Real-World" Problem implementiert werden konnte. – Winterflags

1

Wie wäre es, für Ihr Beispiel

new_list = [v for i, v in enumerate(myList) 
      if myList[3*int(i/3)+2] != 'wrong'] 

Dies funktioniert, da Sie die gesamte Gruppe von 3 Artikeln nicht-kopieren wollen, die Ende mit "falsch". Es wäre komplizierter, wenn Sie nur einen Teil dieser Gruppe oder einige Elemente löschen möchten, die sich nicht in dieser Gruppe befinden. Wenn Sie zum Beispiel den ‚falschen‘ Wert und den Wert, kurz bevor es löschen wollten, könnten Sie

new_list = [v for i, v in enumerate(myList) 
      if myList[3*(i/3)+2] != 'wrong' or i % 3 == 0] 
+0

Dank Rory, das ist wahrscheinlich die allgemeinere robuste Antwort. – Winterflags

0

hier eine Lösung mit numpy.delete verwenden. Numpy.delete entfernen Sie die Elemente mit dem Index. So können Sie die entsprechende Übereinstimmung finden und die vorhergehenden so löschen, wie Sie möchten.

In [1]: import numpy as np 
In [2]: myList = ["you", "are", "right", "I", "am", "wrong"] 
In [3]: for i,j in enumerate(myList): 
    if j == 'wrong': 
     out = np.delete(myList,[i-2,i-1,i]).tolist() 
    ....:  
In [4]: out 
Out[1]: ['you', 'are', 'right'] 
+0

Danke für den noppen Vorschlag, werte es aus! – Winterflags