Удалить все элементы из списка после определенного значения

приведенный список l1 = ['apple', 'pear', 'grapes, 'banana']

Как я могу удалить все элементы после 'pear'

6 ответов


использовать метод среза списка

>>> l1 = ['apple', 'pear', 'grapes', 'banana']
>>> target_ibdex = l1.index('pear')
>>> target_ibdex
1
>>> l1[:target_ibdex+1]
['apple', 'pear']
>>> 

С обработкой исключений, когда элемент отсутствует в списке.

>>> l1 = ['apple', 'pear', 'grapes', 'banana']
>>> target_element = "mango"
>>> try:
...     target_index = l1.index(target_element) + 1
... except ValueError, e:
...     target_index = None
... 
>>> l1[:target_index]
['apple', 'pear', 'grapes', 'banana']

, если элемент присутствует в списке

>>> l1 = ['apple', 'pear', 'grapes', 'banana']
>>> target_element = "pear"
>>> try:
...     target_index = l1.index(target_element) + 1
... except ValueError, e:
...     target_index = None
... 
>>> l1[:target_index]
['apple', 'pear']

l1 = ['apple', 'pear', 'grapes', 'banana']
if "pear" in l1:
    l2 = l1[:l1.index("pear")+1]
    print l2

выход:

['apple', 'pear']


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

def takewhile_including(iterable, value):
    for it in iterable:
        yield it
        if it == value:
            return

l1 = ['apple', 'pear', 'grapes', 'banana']
print('Until pear', list(takewhile_including(l1, 'pear')))
# Until pear ['apple', 'pear']
print('Until blah', list(takewhile_including(l1, 'blah')))
# Until blah ['apple', 'pear', 'grapes', 'banana']

Ну, мне было интересно, насколько быстро каждое решение. Вот код и оценки:

setup = """
from itertools import takewhile, dropwhile

def dropwhile_v1(iterable, sentinel):
    return reversed(list(dropwhile(lambda x: x != sentinel, reversed(iterable))))

def dropwhile_v2(iterable, sentinel):
    return list(dropwhile(lambda x: x != sentinel, iterable[::-1]))[::-1]


def dropwhile_jon(iterable, sentinel):
    for item in iterable:
        yield item
        if item == sentinel:
            return

def dropwhile_vivek(iterable, sentinel):
    try:
        target_index = iterable.index(sentinel) + 1
    except ValueError:
        target_index = None

    return iterable[:target_index]

def dropwhile_autonomou(iterable, sentinel):
    if sentinel in iterable:
       slice = [fr for fr in iterable[:fruits.index(sentinel)+1]]
       return slice


from random import uniform
seq = [uniform(1,100) for _ in range(100)]

def test(callable):
    sentinel = uniform(1,100)
    callable(seq, sentinel)
"""

import timeit
for method in ['dropwhile_v1', 'dropwhile_v2', 'dropwhile_vivek', 'dropwhile_jon', 'dropwhile_autonomou']:
    print ('%s: %fs' % (method, timeit.timeit('test(%s)' % method, setup=setup, number=1000000)))

выход:

dropwhile_v1: 12.979626s
dropwhile_v2: 13.234087s
dropwhile_vivek: 3.883617s
dropwhile_jon: 0.622481s
dropwhile_autonomou: 2.100633s

l1 = ['apple', 'pear', 'grapes', 'banana']
l1 = [x for x in l1[0:l1.index(<target>)+1]]

абстрагирование его в функцию, для модульности и повторного использования было бы идеальным.

>>> li
['apple', 'orange', 'pear', 'tomato']
>>> 
>>> def slice_and_dice(fruit, fruits):
...    
        if fruit in fruits:
...        slice = [fr for fr in l1[:fruits.index(fruit)+1]]
...        return slice
... 
>>> slice_and_dice('pear', li)
['apple', 'orange', 'pear']

есть dropwhile на itertools что можно использовать для фильтрации элементов, после вашего выбора, а затем вы можете взять минус и вы получите то, что вы хотите :

from itertools import dropwhile

dictionary = ['apple', 'pear', 'grapes', 'banana']
filtered = dropwhile(lambda t: 'pear' not in t, dictionary)
next(filtered)
print(list(set(dictionary)-set(list(filtered)))

это будет o / p, как:

['apple', 'pear']