从列表中删除特定值之后的所有元素

Posted

技术标签:

【中文标题】从列表中删除特定值之后的所有元素【英文标题】:Remove all elements from a list after a particular value 【发布时间】:2015-03-26 00:28:50 【问题描述】:

给定一个列表l1 = ['apple', 'pear', 'grapes, 'banana']

如何删除'pear'之后的所有项目

【问题讨论】:

你可以切到它 - l1[:2]. 【参考方案1】:

使用列表切片方法

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

【讨论】:

你应该检查元素是否是列表的一部分或尝试..catch ValueError 而不是target_index = len(l1) - 你可以使用target_index = None【参考方案2】:

您可以构建一个自定义生成器函数,该函数将适用于任何可迭代的,而不仅仅是列表 - 尽管对于您的示例 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']

【讨论】:

【参考方案3】:
l1 = ['apple', 'pear', 'grapes', 'banana']
if "pear" in l1:
    l2 = l1[:l1.index("pear")+1]
    print l2

输出:

['苹果','梨']

【讨论】:

【参考方案4】:

嗯,我对每种解决方案的速度很感兴趣。这是代码和估计:

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

【讨论】:

要正确测试dropwhile_jon - 您需要具体化一个列表,以便将苹果与苹果进行比较 - 否则,测试只是初始化生成器函数 还有“水果”,我认为它应该是“可迭代的”。 除此之外,您应该对所有方法使用相同的哨兵进行测试,而不是随机的。【参考方案5】:

itertools 中有一个 dropwhile,您可以使用它来过滤您选择之后出现的元素,然后您可以减去两者,您将得到您想要的:

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)))

它会像这样运行:

['apple', 'pear']

【讨论】:

【参考方案6】:
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']

【讨论】:

你的 [fr for fr in l1[:fruits.index(fruit)+1]] 可以写成 l1[:fruits.index(fruit)+1]。这里的列表推导没有任何好处。 如果我在其中包含条件,它也可能会更短,我对列表理解的好处更容易阅读,对每个人来说都不一样。 啊,酷,我明白你的意思了。我误读了你之前的意思。决定根据您的建议重新编写以取乐fpaste.org/181051/14229894【参考方案7】:
    l1=(["apple","pear","banana"]) 
    del l1[1:]

删除列表项 1 之外的任何内容(苹果为 0)

【讨论】:

以上是关于从列表中删除特定值之后的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

从包含特定字符的列表中删除元素[重复]

从Python列表中的特定位置删除项目[重复]

python从列表中删除元素

使用 JQuery 从列表中删除除前 N 个元素之外的所有元素

删除或更改列表中特定的重复元素(并非所有重复元素)

如何从列表中删除一个特定元素[重复]