方括号内加星号的表情

时间:2019-04-03 13:44:32

标签: python numpy syntax

似乎加星号的表达式不能像在括号内那样在方括号内使用:

>>> import numpy as np
>>> x = np.ones((3, 4))
>>> x[:, *(None, None), :]
  File "<stdin>", line 1
    x[:, *(None, None), :]
         ^
SyntaxError: invalid syntax

尽管人们期望后者输出与

相同
>>> x[(slice(None), *(None, None), slice(None))]
array([[[[ 1.,  1.,  1.,  1.]]],


       [[[ 1.,  1.,  1.,  1.]]],


       [[[ 1.,  1.,  1.,  1.]]]])

您知道为什么不允许这样做的任何充分理由,以及是否有计划在下一个Python版本中支持它吗?

1 个答案:

答案 0 :(得分:2)

关于如何执行此操作,答案可能是x[:, None, None, :]。但是也许您有一个包含nones = (None, None)的元组,在这种情况下,您可以这样做:x[:, nones[0], nones[1], :]。但是我同意让x[:, *nones, :]有效会更好。

关于这个问题,为什么不可能,我们可以看看Python grammar来看看为什么不起作用:

trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
subscript: test | [test] ':' [test] [sliceop]
sliceop: ':' [test]

如果您遵循test中最长,最有前途的语法分支,请搜索'*'文字(我不会显示整个子树,因为大多数其他分支都在很早就停止了):{{1 }}。

请注意,我们正在搜索的规则是

test -> or_test -> and_test -> comparison -> xor_expr -> and_expr -> shift_expr -> arith_expr

让我们看看是否可以从这里(star_expr: '*' expr )找到它:

arith_expr

请记住,arith_expr: term (('+'|'-') term)* term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom_expr ['**' factor] atom_expr: ['await'] atom trailer* 是我们的起点,所以我们已经知道没有什么可以导致trailer到这里了,star_expr封闭了所有这些不同的路径:

atom

基本上,只允许您将我们在分支中看到的任何表达式(atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') subscriptlist中的任何表达式用作test -> ... -> arith_expr -> ... -> atom

我没有在这里经历过很多分支。对于其中大多数人,只需查看规则名称即可了解原因。另一方面,仔细检查可能并非没有用。

例如,当读取表达式NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False'时:

test

我们可以看到test: or_test ['if' or_test 'else' test] | lambdef 关闭了路径(正如我们在寻找['if' or_test 'else' test]一样)。另一方面,我本可以包含* something,因为这对于我们的任务是完全有效的,我只是忽略了这样的路径,因为在我们探索它们之后(应用单个规则invalidades lambdef),它们会立即关闭,这种情况(您可能已经猜到了):

*...

我们在这里看到一个lambdef: 'lambda' [varargslist] ':' test ,它不是一个以'lambda'开头的表达式,所以路径关闭了。有趣的是,这意味着'*'是完全有效的语法(我不会猜,也从未见过,但这很有意义)。

最后,在此过程中,我们没有看到任何单个前导x[lambda e: e]表达式,因此,您提出的建议应该没有歧义(除非我错过了规则的组合)。可能会问真正从事过此工作的人检查是否有充分的理由不存在这种潜在的语法歧义。