找到第一个 True 时停止循环

igo*_*rkf 2 python for-loop list-comprehension break

当我找到第一个 True 时,我想停止迭代,如下所示:

>> for x in ['a', 'b', 1, 2, 3]:
>>    if isinstance(x, int):
>>        print(x)
>>        break

 1
Run Code Online (Sandbox Code Playgroud)

我怎样才能做同样的事情但使用列表理解for 循环?

C.N*_*ivs 6

您可以next在生成器表达式上使用以返回第一个True实例:

x = next((a for a in ['a', 'b', 1, 2, 3] if isinstance(a, int)), None)
print(x)
1

x = next((a for a in ['a', 'b'] if isinstance(a, int)), None)
print(x)
None
Run Code Online (Sandbox Code Playgroud)

其中第二个参数是允许您避免StopIteration错误的返回值

编辑(信用@martineau)

这可以简化为filter运算符,如上面的 itertools 配方所示:

x = next(filter(int.__instancecheck__, ['a', 'b', 1, 2, 3]), None)
Run Code Online (Sandbox Code Playgroud)


jir*_*mok 5

不幸的是,没有内置机制来查找与谓词匹配的列表的第一个元素。还有any,你可以用它来确定是否存在这样一个元素,但不会告诉你那是什么元素。

any(isinstance(x, int) for x in ['a', 'b', 1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

幸运的是,itertools当您想对列表或任何其他可迭代对象进行某些操作时,它提供了多种功能。

您要查找的函数并未内置到模块中,但文档提供了一些函数的定义,包括这个函数,作为itertools recipes。您需要的函数名为first_true。只需复制定义,然后:

def first_true(iterabe, default=False, pred=None):
    return next(filter(pred, iterable), default)

x = first_true(['a', 'b', 1, 2, 3], pred=int.__instancecheck__)
Run Code Online (Sandbox Code Playgroud)

如果列表中没有与谓词匹配的内容,first_true则返回False。如果您想要不同的行为,可以修改该函数。如果您想了解如何使用 itertools 风格的迭代器,其他食谱可能是一个很好的起点。


但是,如果您试图在循环中进行更复杂的处理,而不仅仅是找到第一个匹配元素,那么最好使用适当的for循环。列表推导式和生成器表达式可以很好地替代 map 和 filter,并且 itertools 提供了更通用的可迭代操作,但它们并不意味着代表真正的循环逻辑。