Rom*_*rés 5 python syntax numpy
似乎星号表达式不能像在括号内那样在方括号内使用:
>>> import numpy as np
>>> x = np.ones((3, 4))
>>> x[:, *(None, None), :]
File "<stdin>", line 1
x[:, *(None, None), :]
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
尽管人们会期望后者输出与
>>> x[(slice(None), *(None, None), slice(None))]
array([[[[ 1., 1., 1., 1.]]],
[[[ 1., 1., 1., 1.]]],
[[[ 1., 1., 1., 1.]]]])
Run Code Online (Sandbox Code Playgroud)
您是否知道不允许这样做的任何充分理由,以及是否有计划在下一个 Python 版本中支持它?
至于如何做到这一点,答案可能是x[:, None, None, :]。但也许你有一个包含 的元组nones = (None, None),在这种情况下你可以这样做:x[:, nones[0], nones[1], :]。但我同意这如果有效的话会更好x[:, *nones, :]。
关于为什么不行的问题,我们可以看一下Python语法,看看为什么不行:
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
subscript: test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
Run Code Online (Sandbox Code Playgroud)
如果您遵循 中最长且最有希望的语法分支test,搜索'*'文字(我不呈现整个子树,因为大多数其他分支很早就停止):test -> or_test -> and_test -> comparison -> xor_expr -> and_expr -> shift_expr -> arith_expr。
请注意,我们正在搜索的规则是这个
star_expr: '*' expr
Run Code Online (Sandbox Code Playgroud)
让我们看看是否可以从这里找到它(arith_expr):
star_expr: '*' expr
Run Code Online (Sandbox Code Playgroud)
请记住,trailer这是我们开始的地方,所以我们已经知道没有任何东西通向star_expr这里,并atom关闭所有这些不同的路径:
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom_expr ['**' factor]
atom_expr: ['await'] atom trailer*
Run Code Online (Sandbox Code Playgroud)
基本上,您应该只被允许使用subscriptlist我们在分支 ( test -> ... -> arith_expr -> ... -> atom) 或NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') 中看到的任何表达式。
这里还有很多分行我没有经过。对于大多数规则,您只需查看规则名称就可以理解原因。另一方面,仔细检查可能也不是没有用。
例如,当读取表达式时test:
atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [testlist_comp] ']' |
'{' [dictorsetmaker] '}' |
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
Run Code Online (Sandbox Code Playgroud)
我们可以看到['if' or_test 'else' test]关闭了路径(正如我们正在寻找的那样* something)。另一方面,我可以包含在内,lambdef因为这对于我们的任务完全有效,我只是忽略了这些路径,因为它们在我们探索它们之后立即关闭(应用单个规则 invalidades *...),在这种情况下(正如您可能已经猜到的那样):
test: or_test ['if' or_test 'else' test] | lambdef
Run Code Online (Sandbox Code Playgroud)
我们在这里看到 a 'lambda',它不是一个以 so 开头的表达式,'*'因此路径关闭。有趣的是,这意味着这x[lambda e: e]是完全有效的语法(我不会猜到,我也从未见过它,但它是有道理的)。
最后,我们*在这个过程中没有看到任何一个主导表达式,因此你的建议应该没有歧义(除非我错过了一种规则组合)。也许向真正从事过此工作的人询问是否有充分的理由不存在这种外部潜在的语法歧义是有意义的。