Python中for循环与推导式的差异及any()调用报错问题求解
首先明确Python内置any()函数的核心规则:any()要求传入的参数必须是可迭代对象(比如生成器、列表、元组等),它会遍历该对象的所有元素,只要存在一个元素为真就返回True,所有元素都为假则返回False。
第一段代码正常运行的原因
你传给any()的参数是c.isalnum() for c in s,这是一个生成器表达式,本身就是合法的可迭代对象:它会逐个遍历字符串s的字符,计算每个字符的isalnum()结果,把这些布尔值逐个返回给any()做判断。
补充说明:你推测的“推导式先把布尔值存到列表”并不完全准确,生成器是惰性计算的,不会提前把所有结果存储到内存,只有当any()需要下一个判断值时才会生成对应结果;哪怕你换成列表推导式[c.isalnum() for c in s]传入也能运行,本质都是传入了符合要求的可迭代对象。
第二段代码报错的原因
你已经写了外层for c in s循环,每次循环拿到的是单个字符c,调用c.isalnum()得到的是单个布尔值(比如第一个字符t的判断结果就是单个True,不是可迭代对象),直接把单个布尔值传给要求可迭代参数的any(),自然会抛出bool is not iterable的错误,和推导式没有任何关系,只是参数类型不符合any()的调用要求。
对你的推测的纠正
你的理解存在偏差,推导式没有特殊的布尔值处理逻辑,两段代码的核心差异是你传给any()的参数类型完全不同:第一次传的是可迭代的生成器,第二次传的是单个布尔值。
如果要在普通for循环中实现和第一段代码一样的效果,需要先把所有布尔值收集为可迭代对象再传入any(),示例如下:
s = "test123" res_list = [] for c in s: res_list.append(c.isalnum()) print(any(res_list))
内容的提问来源于stack exchange,提问作者Akhmet Yeleukenov

