当我需要根据某些条件从列表的两端删除一些元素时,我遇到了一些问题。例如,假设我想从列表的两端删除元素,一旦遇到第一个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} }。用右侧重复相同的步骤。
使用这个逻辑,我用两个循环完成它,完全如上所述。但它似乎有点复杂。有没有更简单的方法来处理这样的任务?
答案 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])]
适合我的情况,但不是很普遍...