当前位置: 首页 > 知识库问答 >
问题:

在满足条件之前过滤掉所有元素,之后保留所有元素

巴博耘
2023-03-14

我想知道下面的问题是否有一个简单的解决方案。这里的问题是,我希望在初始条件为真后保留列表中出现的每个元素。这里的条件是,我想删除值大于18的条件之前的所有内容,但保留之后的所有内容。示例

输入:

p = [4,9,10,4,20,13,29,3,39]

预期产出:

p = [20,13,29,3,39]

我知道你可以通过

[x for x in p if x>18] 

但是我想一旦找到18以上的第一个值就停止这个操作,然后包括其余的值,不管它们是否满足条件。这似乎是一个简单的问题,但我还没有找到解决办法

共有3个答案

百里泓
2023-03-14

伟大的解决方案在这里,只是想演示如何做到这一点与Numpy:

>>> import numpy as np
>>> p[(np.array(p) > 18).argmax():]
[20, 13, 29, 3, 39]

因为这里有很多很好的答案,所以我决定运行一些简单的基准测试。第一个使用OP的示例数组([4,9,10,4,20,13,29,3,39]),长度为9。第二个使用随机生成的长度2万数组,其中前半部分在0到15之间,后半部分在-20到30之间(这样分裂就不会发生在中心)。

使用OP的数据(长度为9的数组):

%timeit enke()
650 ns ± 15.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit j1lee1()
546 ns ± 4.22 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit j1lee2()
551 ns ± 19 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit j2lee3()
536 ns ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit richardec()
2.08 µs ± 16 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

使用长度为20000(20000)的数组:

%timeit enke()
1.5 ms ± 34.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit j1lee1()
1.95 ms ± 43 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit j1lee2()
2.1 ms ± 53.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit j2lee3()
2.33 ms ± 96.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit richardec()
13.3 µs ± 461 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

生成第二个数组的代码:

p = np.hstack([np.random.randint(0,15,10000),np.random.randint(-20,30,10000)])

所以,对于小情况,Numpy是一个鼻涕虫,不需要。但大的情况下,Numpy几乎是100x倍的速度和方式去!:)

朱海超
2023-03-14

您可以使用枚举并在下一步中列出切片:

out = next((p[i:] for i, item in enumerate(p) if item > 18), [])

输出:

[20, 13, 29, 3, 39]
松英喆
2023-03-14

你可以使用itertools。dropwhile

import itertools

p = [4,9,10,4,20,13,29,3,39]

p = list(itertools.dropwhile(lambda x: x <= 18, p))
print(p) # [20, 13, 29, 3, 39]

使用walrus操作符(不使用itertools,但仅在python 3.8中可用):

exceeded = False
p = [x for x in p if (exceeded := exceeded or x > 18)]
print(p) # [20, 13, 29, 3, 39]

但我猜有些人不喜欢这种风格。在这种情况下,您可以将其展开为:

output = []
exceeded = False
for x in p:
    exceeded = exceeded or x > 18
    if exceeded:
        output.append(x)

print(output) # [20, 13, 29, 3, 39]
 类似资料:
  • 假设我有这样的html: 我只想获得之前的 。有没有办法用JSOUP做到这一点呢?我知道我可以把所有的宠物都弄成这样: 但这也包括额外的宠物。我想知道我是只能选择上面的宠物还是只是删除下面的宠物然后使用那个代码?

  • 问题内容: 我对如何在Java中执行此操作有一般的想法,但是我正在学习Python,但不确定如何执行。 我需要实现一个函数,该函数返回一个包含列表中所有其他元素的列表,从第一个元素开始。 到目前为止,我不确定从这里开始该怎么做,因为我只是在学习Python中的for循环是如何不同的: 问题答案:

  • 我有一个项目,我的方法得到两个日期,它不断地向方法添加一天,直到两个日期相等,然后您可以通过查看一天添加了多少次来查看日期相距有多远。我的问题是,当满足日条件时,即使日、月和年必须都相同才能停止工作,我的while循环也会退出

  • 从数组中移除 falsey 值元素。 使用 Array.filter() 过滤掉数组中所有 假值元素(false, null, 0, "", undefined, 和 NaN)。 const compact = arr => arr.filter(Boolean); compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); //

  • 假设我有这个HTML: 现在我要访问 ,它与标记在同一个tr中,带有href“Amazon”。最好的方法是什么?我需要一个for循环覆盖所有的div吗?还是我可以使用@findby注释?我是否需要多个@findby或@findall来获取列表中的所有div以便为Amazon检查这些div?

  • 我试图将JSON中的数据保存到数组中,但最后一项覆盖了前面的值。我有一个用于存储学生信息的学生类和一个用于存储学生技能的技能类。 学生班 我在技能数组上循环,并将其附加到我的数组,并打印最后一个附加的值,正确的值被打印出来。 在循环中,从上述