根据条件切割清单尾部

时间:2013-11-03 23:54:02

标签: python list slice

当我需要根据某些条件从列表的两端删除一些元素时,我遇到了一些问题。例如,假设我想从列表的两端删除元素,一旦遇到第一个0(包括第一个0),就从位置q开始。

示例:

mylist = [1,1,0,1,0,1,2,3,1,5,1,3,1,0,2]

应该成为:

[1,2,3,1,5,1,3,1]

如果我们将q取为7.所以,我们转到第7个元素,开始向左移动,当遇到第0个时,我们记住索引i0并将其切断{{1} }。用右侧重复相同的步骤。

使用这个逻辑,我用两个循环完成它,完全如上所述。但它似乎有点复杂。有没有更简单的方法来处理这样的任务?

3 个答案:

答案 0 :(得分:2)

就个人而言,我特意做的就是向后看零,只返回索引并正确调整它以引用回原始列表。我担心这可能不是很清楚,所以让我告诉你我在代码中的含义:

zero = lambda l: next(i for i,v in enumerate(l) if v==0)
ending_zero = q + zero(mylist[q:])
starting_zero = q - zero(mylist[:q:-1])
return mylist[starting_zero:ending_zero]

或者将它包装在函数中并添加一些一般要求(不一定等于零)

def two_directional_slice(original, condition, q):
    condition = lambda l: (i for i,v in enumerate(l) if condition(v)).next()
    ending_condition = q + condition(mylist[q:])
    starting_condition = q - condition(mylist[:q:-1])
    return mylist[starting_condition:ending_condition]

由于它懒惰地评估了条件,我认为你通常最好不要使用它,甚至迭代一次,但在最坏的情况下,这将在你的列表中重复一次。

为了彻底,这里是你如何使用最后一个实现来解决第一个问题:

return two_directional_slice(mylist, lambda x: x==0, 7)

答案 1 :(得分:1)

这是一个非常有效的双线解决方案,使用itertools.takewhile

>>> mylist = [1,1,0,1,0,1,2,3,1,5,1,3,1,0,2]
>>> q = 7
>>>
>>> from itertools import takewhile as tw
>>> list(tw(bool, mylist[q::-1]))[::-1] + list(tw(bool, mylist[q+1:]))
[1, 2, 3, 1, 5, 1, 3, 1]
>>>

这里重要的是0评估为False。这意味着当数字不等于0时,您可以“接受”。

答案 2 :(得分:0)

刚想出来:

[mylist[i] for i in range(len(mylist)) if i==q or (i < q and 0 not in mylist[i:q+1]) or (i > q and 0 not in mylist[q:i+1])]

适合我的情况,但不是很普遍...