Python 方括号内的星号表达式
似乎星号表达式在方括号内的使用方式与在括号内的使用方式不同:Python 方括号内的星号表达式,python,numpy,syntax,Python,Numpy,Syntax,似乎星号表达式在方括号内的使用方式与在括号内的使用方式不同: >>将numpy作为np导入 >>>x=np.one((3,4)) >>>x[:,*(无,无),:] 文件“”,第1行 x[:,*(无,无),:] ^ SyntaxError:无效语法 尽管人们会期望后者的产出与之相同 >>> x[(slice(None), *(None, None), slice(None))] array([[[[ 1., 1., 1., 1.]]], [[[ 1.,
>>将numpy作为np导入
>>>x=np.one((3,4))
>>>x[:,*(无,无),:]
文件“”,第1行
x[:,*(无,无),:]
^
SyntaxError:无效语法
尽管人们会期望后者的产出与之相同
>>> x[(slice(None), *(None, None), slice(None))]
array([[[[ 1., 1., 1., 1.]]],
[[[ 1., 1., 1., 1.]]],
[[[ 1., 1., 1., 1.]]]])
你知道为什么不允许这样做吗?如果有计划在下一个Python版本中支持它的话?至于如何做到这一点,答案可能是
x[:,无,无,:]
。但可能您有一个元组包含nones=(None,None)
,在这种情况下,您可以执行:x[:,nones[0],nones[1],:]
。但我同意,如果x[:,*nones,:]
有效,这会更好
关于“为什么不可能”的问题,我们可以看一下,看看为什么这不起作用:
trailer:“(“[arglist]”)“|”[“subscriptlist]””]“|”名称
下标列表:下标(','下标)*[',']
下标:test |[test]:'[test][sliceop]
切片器:':'[测试]
如果您遵循test
中最长、最有前途的语法分支,搜索“*”
文字(我不会显示整个子树,因为大多数其他分支都很早就停止):test->或\u test->和\u test->比较->异或表达式->和\u expr->shift\u expr->arith\u expr
请注意,我们正在搜索的规则就是这个
star_expr: '*' expr
让我们看看是否可以从这里找到它(arith\u expr
):
arith_expr:term(“+”|“-”)term)*
术语:因子(“*”|“@”|“/”|“%”|“/”)因子)*
因子:(“+”|“-“|”~”)因子功率
功率:原子表达式['**'因子]
atom_expr:['wait']atom拖车*
请记住,trail
是我们的起点,因此我们已经知道这里没有任何东西会导致star\u expr
,而atom
会关闭所有这些不同的路径:
原子:(“(“[yield_expr | testlist_comp]”)|
“[”[testlist_comp]”|
“{'[dictorsetmaker]'}”|
名称|编号|字符串+|'…'|'无'|'真'|'假')
基本上,您应该只允许作为子列表使用我们在分支中看到的任何表达式(test->…->arith_expr->…->atom
)或NAME | NUMBER | STRING+|“…”中的任何表达式
这里有很多我没有穿过的树枝。对于大多数人来说,只要看一下规则的名称就可以理解为什么。另一方面,反复检查可能不是没有用的
例如,当读取表达式测试时:
test:or_test['if'或_test'else'测试]| lambdef
我们可以看到,['if'或_test'else'test]
关闭了路径(因为我们正在寻找*某物
)。另一方面,我可以包含lambdef
,因为这对我们的任务非常有效,我只是忽略了这些路径,因为它们在我们探索它们之后立即关闭(应用单个规则invalidades*…
),在这种情况下(正如您可能猜到的):
lambdef:'lambda'[varargslist]':'test
我们在这里看到一个'lambda'
,它不是一个以'*'
开头的表达式,因此路径关闭。有趣的是,这意味着x[lambda e:e]
是完全有效的语法(我不会猜到,我也从未见过它,但它是有意义的)
最后,在这个过程中,我们没有看到一个前导的*
表达式,因此您的建议应该没有歧义(除非我遗漏了一个规则组合)。也许,让实际从事这项工作的人检查一下,除了潜在的语法歧义之外,是否有一个很好的理由不存在这一点是有道理的。[*]
只会在numpy
中使用。常规python索引只允许一个值<代码>(*)
出现在许多地方,有时没有()常规python索引实际上允许多个输入。它们被收集在一个元组中,该元组被传递给容器的\uuu getitem\uuu
方法。其他库,如pandas
,pytorch
等,也使用numpy
多索引样式,所以我不会说它只是一个与numpy
相关的问题!事实上,星号表达式可以在没有括号的情况下使用,但调用容器[*项]
与函数(*args)
类似,也就是说添加了\uu getitem\uuuuu
元组,因为numpy
需要它。所有内置Python对象都没有使用它。我有pandas
和pytorch
作为numpy
衍生品。您甚至可以编写自己的类来利用该特性。我提出这一点只是为了争辩说,[*]
对Python的核心没有多大用处。Tuple*扩展用于隐含()的情况。事实上,定义元组的是逗号,而不是()。然而,我对形式语法了解不够,无法说明解包中使用的*
是否与函数参数和元组中的用法相同。我怀疑这一切都是由同一个分支机构处理的。实际上,*
在列表中确实有效,[*abc]=1,2,3
<代码>[*abc]
。但是索引括号不会创建列表。这个问题可能是头脑风暴,它确实属于PEP或Python开发板。