Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于条件的切割列表_Python_List_Slice - Fatal编程技术网

Python 基于条件的切割列表

Python 基于条件的切割列表,python,list,slice,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,并将其切掉mylist=mylist[i0+1://code>。对右侧重复相同的步骤 使用这个逻辑,我用两个

有几次,当我需要根据某种条件从列表的两端删除一些元素时,我遇到了一个问题。例如,假设我想从列表的两端删除元素,只要遇到第一个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
,并将其切掉
mylist=mylist[i0+1://code>。对右侧重复相同的步骤


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

刚刚想到了这个:

[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])]
[mylist[i]表示范围内的i(len(mylist)),如果i==q或(iq且0不在mylist[q:i+1])]

在我的情况下是有效的,但不是非常通用的…

就我个人而言,我具体的做法是向后看零,然后返回索引,并适当地调整它以引用原始列表。我担心这可能不是非常清楚,所以让我向您展示我在代码中的意思:

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]
或者将其包装在函数中并添加一些一般要求(不一定等于零)

由于它懒散地评估条件,我认为使用它通常比只迭代一次要好,但在最坏的情况下,它会在列表中只迭代一次

为了全面起见,以下是您将如何使用最后一个实现解决第一个问题:

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

这是一个非常高效的两行解决方案,它使用:


这里重要的是
0
的计算结果为
False
。这意味着,当数字不等于
0

时,您可以“接受”,但如果我看到有人将此放在我正在管理的代码库中,我不会让它通过代码审查。它有效吗?当我用
q=7
运行它时,我得到
[1,2,1,5,1,3,1,0]
。这与给出的示例输出不同。末端有一个
0
应该在那里,对吗?为什么它很复杂?任何答案都必须相当于遍历这些值并检查这些位置的零。我看不出答案会如何改进您已有的代码。@SimeonVisser可能是因为之前的解决方案隐含了两次完整的迭代?我认为懒洋洋地只评估列表中相关部分的条件是一种合理的改进,但绝对不是惊天动地的。@SimeonVisser通过缩短代码:)@sashkello:短代码不一定是好代码。将
(…).next()
更改为
next(…)
,它也适用于Python 3。另外,通过切片创建两个新列表,因此我认为除非使用
itertools.islice
,否则这个解决方案实际上不会更快。
return two_directional_slice(mylist, lambda x: x==0, 7)
>>> 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]
>>>