Python 查找列表中的第一个元素和索引匹配条件
考虑这个简单的例子Python 查找列表中的第一个元素和索引匹配条件,python,list,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子句查找正确
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函数
谢谢 你可以在列表中完成。这基本上与您的代码相同,但压缩为一行,它构建了一个符合条件的结果列表 第一种方法获得所有匹配项
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
像这样的方法应该会奏效:
l=[-1,-2,3,4,5,6]
列表(对于l中的x,x>0)。索引(True)
#产出:2
为了找到所有模式,我们可以使用python内置函数
来自itertools导入过滤器False
f=filterfalse(lambda x:x[1]您可以使用lambda
和filter
的组合,如下所示:
mylist = [-1,-2,3,4,5,6]
myidx, myel = list(filter(lambda el: el[1] > 0, enumerate(mylist)))[0]
print("({}, {})".format(myidx, myel))
说明:
filter()
函数提供了一种优雅的方式来过滤掉所有元素,它将函数和列表作为参数。它们是lambda
和mylist
。由于您想要获得相应的索引,我们需要使用enumerate
来总结enumerate(mylist)
基本上,enumerate(mylist)
返回一个索引和相应值的元组。这里的条件是值和0
之间的比较,所以我们得到el[1]
而不是el[0]
来与0
进行比较
结果将被转换到列表
。此列表包括符合我们条件的所有对(索引,值)
。这里我们想要得到第一对,因此我们在末尾有[0]
输出:
(2, 3)
很有趣,但我不明白这里发生了什么。列表不是返回了真-假布尔值吗@ℕʘʘḆḽḘ 它逐个检查元素并检查子句x>0
。因此列表将转换为[False,False,True,…]
。然后index()
在列表中找到第一个True
元素是的,但我对索引和元素都感兴趣@ℕʘʘḆḽḘ 使用Python内置的filterfalse
nice是可行的,但是多个匹配呢?这应该会找到所有元素>0
,并返回一个包含索引和元素的元组列表。我实际上没有运行它。啊,等等,我只是运行了它,我正在比较索引。我现在就编辑它,使它输出的结果与您的相同。是的,我不是真的ise您只需要一个结果。生成器表达式是这种情况下最好的方法。很有趣,谢谢!您能在这里进一步解释一下逻辑吗?我更新了我的答案,添加了解释。