关于Python中all()函数参数的疑问:为何生成器表达式作为参数可正常运行?
嘿,这个问题问得特别好!让我一步步给你理清楚~
首先得明确:all()函数的定义就是只接受一个参数,这个参数必须是一个可迭代对象(比如列表、元组、生成器、集合等等)。所以all(1, 0)直接传了两个位置参数,肯定会触发参数数量不匹配的错误,这很好理解。
那为什么all(y for y in [1,0])能正常运行呢?其实这里的关键不是什么“隐式转成列表/元组”,而是y for y in [1,0]本身就是一个生成器表达式——而生成器表达式本身就是一个合法的可迭代对象,刚好符合all()对参数的要求。
至于为什么看起来没给这个生成器表达式加括号?这是Python的一个语法糖:当生成器表达式作为函数的唯一实参时,你可以省略包围它的圆括号。换句话说,这段代码完全等价于:
all((y for y in [1,0]))
只是省略括号后写法更简洁而已。
再补充一下文档里的依据:
- 在
all()函数的官方说明里,明确标注它的参数是iterable(可迭代对象); - 在Python的生成器表达式语法规则中,专门提到了“当生成器表达式是函数调用的唯一实参时,圆括号可以省略”这一点。
举个类似的例子你就更清楚了:list(y for y in range(3))和list((y for y in range(3)))是完全一样的效果,都是把生成器里的元素转成列表。但如果函数有多个参数,那生成器表达式的括号就不能省了,比如my_func((y for y in [1,0]), "hello"),要是去掉括号写成my_func(y for y in [1,0], "hello")就会报错。
总结一下:all(y for y in [1,0])能运行,本质是因为生成器表达式本身是可迭代对象,刚好满足all()单参数的要求,再加上Python允许省略唯一参数时生成器的括号,才让这段代码看起来有点“特殊”~
备注:内容来源于stack exchange,提问作者BigFatMax

