如何找出Python内置函数any中未通过验证的元素?
好问题!原生的any()函数本身确实没办法直接告诉你哪个元素没通过验证——它的设计目标只是返回True或False,告诉你是否存在满足条件的元素,而不会记录具体是哪一个。
先说说any()的精确实现
官方文档给出的等价Python代码完全反映了它的核心逻辑:
def any(iterable): for element in iterable: if element: return True return False
CPython底层是用C语言实现的,但执行逻辑和这段代码完全一致:遍历可迭代对象,遇到第一个为真的元素就立刻返回True,遍历完所有元素都没找到符合条件的就返回False。全程不会保存任何元素的信息,所以自然没法定位到具体哪个元素导致了结果。
如何实现你的需求:找出乘积无法整除的数字
针对你解决欧拉计划第5题的场景,如果你想保持类似any()的短路效率(找到第一个不满足条件的数字就停止遍历),可以用**生成器表达式配合next()**来实现,既简洁又高效:
假设你的候选乘积是candidate_product,要检查的数字范围是1到20:
# 找到第一个无法整除候选乘积的数字 first_non_divisor = next( (num for num in range(1, 21) if candidate_product % num != 0), None # 如果所有数字都能整除,返回None )
这个写法和any()的执行逻辑几乎一模一样:逐个检查数字,一旦找到第一个candidate_product % num != 0的数就立即返回,剩下的数字不会再遍历,完美兼顾了效率和结果获取。
如果需要找出所有无法整除的数字,直接用列表推导式即可:
# 获取所有无法整除候选乘积的数字 all_non_divisors = [num for num in range(1, 21) if candidate_product % num != 0]
关于你提到的yield机制
你说的“隐藏的yield机制”其实就是生成器的特性——上面用到的生成器表达式(num for num ...)底层就是通过yield实现的。当你用next()去迭代它时,它会逐个生成元素,直到找到符合条件的那个就停下来,刚好满足你“类似any但能拿到目标元素”的需求。
总结一下:原生any()做不到定位元素,但用生成器配合next()的方式,既能复刻any()的短路效率,又能精准拿到你需要的未通过验证的数字。
内容的提问来源于stack exchange,提问作者CIsForCookies

