在列表中查找第一个元素和索引匹配条件

时间:2021-03-25 02:36:08

标签: python list

考虑这个简单的例子

mylist = [-1,-2,3,4,5,6]

for idx, el in enumerate(mylist):
    if el > 0:
        myidx, myel = idx, el
        break

myidx, myel
Out[20]: (2, 3)

我有兴趣在 python 列表中找到匹配特定条件的第一个索引和相应的第一个元素(这里,这只是 > 0)。

在上面的代码中,我使用 enumerate 遍历元素,然后使用 if 子句查找正确的元素。这对我来说看起来很麻烦。有一个更好的方法吗?例如使用原生 python 函数?

谢谢!

3 个答案:

答案 0 :(得分:2)

你可以在列表理解中做到这一点。这与您的代码基本相同,但浓缩为一行,并构建了符合条件的结果列表。

第一种方式获取所有匹配

mylist = [-1,-2,3,4,5,6]

results = [(i, el) for i, el in enumerate(mylist) if el > 0]

另一种方法是使用可能更快的生成器表达式,然后解压它。这是第一个。

*next((i, el) for i, el in enumerate(mylist) if el > 0))

这会循环列表并检查条件,然后将索引和元素放入一个元组中。在括号内执行此操作会将其转换为生成器,速度要快得多,因为它实际上不必将所有内容都保存在内存中,它只是根据您的需要生成响应。使用 next() 您可以遍历它们。因为我们只在这里使用 next() 一次,所以它只生成第一个匹配项。然后我们用 *

解压它

由于这里还有另外两个有效答案,我决定使用 timeit 模块为每个答案计时并发布结果。为了清楚起见,我还对 OP 的方法进行了计时。这是我发现的:

import timeit
# Method 1 Generator Expression
print(timeit.timeit('next((i, el) for i, el in enumerate([-1,-2,3,4,5,6]) if el > 0)', number=100000))
0.007089499999999999

# Method 2 Getting index of True
print(timeit.timeit('list(x > 0 for x in [-1,-2,3,4,5,6]).index(True)', number=100000))
0.008104599999999997

# Method 3 filter and lambda
print(timeit.timeit('myidx , myel = list(filter(lambda el: el[1] > 0, enumerate([-1,-2,3,4,5,6])))[0]', number=100000))
0.0155314

statement = """
for idx, el in enumerate([-1,-2,3,4,5,6]):
    if el > 0:
        myidx, myel = idx, el
        break
"""

print(timeit.timeit(statement, number=100000))
0.04074070000000002

答案 1 :(得分:2)

这样的事情应该可以工作:

l = [-1,-2,3,4,5,6]
list(x > 0 for x in l).index(True)
# Output: 2

要查找所有模式,我们可以使用 python 内置函数使用

from itertools import filterfalse
f = filterfalse(lambda x: x[1] <= 0, enumerate(l))
print(list(f))
# [(2, 1), (3, 2), (4, 3)]

答案 2 :(得分:1)

您可以像这样使用 lambdafilter 的组合:

mylist = [-1,-2,3,4,5,6]

myidx, myel = list(filter(lambda el: el[1] > 0, enumerate(mylist)))[0]
print("({}, {})".format(myidx, myel))

说明:

filter() 函数提供了一种优雅的方式来过滤掉函数和列表中的所有元素作为参数。它们是 lambdamylist。既然要得到对应的索引,我们就需要用enumerate来包裹enumerate(mylist)

基本上,enumerate(mylist) 返回一个索引和相应值的元组。我们这里的条件是值与 0 之间的比较,这就是为什么我们使用 el[1] 而不是 el[0] 来与 0 进行比较。

结果将被转换为 list。此列表包括满足我们条件的所有对 (index, value)。在这里,我们想要获得第一对,这就是为什么我们在最后有 [0]

输出:

(2, 3)