2016-06-11 1 views
0

Я ищу способ, чтобы удалить все п-й элемент (назовем этот пункт i) в списке, и также х Количество элементов, непосредственно предшествующих i в списке, если i соответствует состоянию.Если элемент в списке соответствует условию, удалить элемент и несколько предыдущих пунктов

Я искал список понятий и итераций, но для новичков было сложно найти решение.

Пример:

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

Для каждого пункта, проверьте i == "wrong": Если да, то удалить i и два(2) пунктов предшествующегоi.

Эффект: Последовательность "I, "am", "wrong" удалена из списка.

+0

Что произойдет, если '' wrong "' встречается в начале списка или если два '' неправильных' 'происходят с менее чем двумя элементами между ними? – BrenBarn

+1

И ... вы думаете, что мы здесь, чтобы написать это для вас? – jonrsharpe

+0

@BrenBarn Спасибо, что спросили! Это никогда не произойдет - в моем примере вы можете найти только «правильные» и «неправильные» на третьем месте. И поскольку три элемента удаляются, если условие выполнено, оно остается таким же. Но для будущих читателей, не связанных с этим правилом, следует рассмотреть порядок списка. – Winterflags

ответ

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'] 

Конечно, вы могли бы сделать 2 переменной

+1

Я считаю, что ваш код работает только в том случае, если длина списка кратна 3, и единственное проверенное значение, которое является «неправильным», является ** последним ** одним. –

+1

Я думаю, что он находит первое появление «неправильного», которое может быть указано как переменная для какой-либо другой строки, а затем берет фрагмент всего от начала до двух значений до «неправильной» позиции. Я согласен, что он не является надежным, но он решает вопрос OP. Он заявил, что его список гарантирует наличие необходимого количества элементов перед триггерной строкой. –

+0

Спасибо, Джоэл. В итоге я использовал это, потому что синтаксис был легче для меня понять, а также был реализован в моей «реальной» проблеме с некоторыми изменениями. – Winterflags

1

Как насчет вашего примера,

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

Это работает так как вы хотите, чтобы не-скопировать всю группу из 3 элементов, что концы с «неправильным». Было бы сложнее, если бы вы хотели удалить только часть этой группы или некоторые элементы, не входящие в эту группу. Если, например, вы хотите, чтобы удалить «неправильный» и значения непосредственно перед ним, вы могли бы использовать

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

Спасибо, Рори, это, вероятно, более универсальный ответ. – Winterflags

0

Здесь решение с numpy.delete. Numpy.delete удалите элементы с помощью индекса. Таким образом, вы можете найти соответствующее совпадение и удалить предыдущие, сколько хотите.

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

Спасибо за предложение numpy, оцените его! – Winterflags

Смежные вопросы