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 循环?
您可以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错误的返回值
这可以简化为filter运算符,如上面的 itertools 配方所示:
x = next(filter(int.__instancecheck__, ['a', 'b', 1, 2, 3]), None)
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有内置机制来查找与谓词匹配的列表的第一个元素。还有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 提供了更通用的可迭代操作,但它们并不意味着代表真正的循环逻辑。