Python中的'@ ='符号是什么?


173

我知道@是给装饰器用的,但是@=Python有什么用呢?只是保留一些未来的想法吗?

这只是我阅读时遇到的许多问题之一tokenizer.py。


1
请参阅CPython存储库中的cset c553d8f72d65(GitHub镜像...更易于阅读)。
— 尼克T

SymbolHound是一个搜索引擎,可以搜索标点符号。但是,在@ = python上搜索当前不会返回相关结果,因为Python 3.5文档在任何地方都包含'@'而不是'@ ='的示例。我向SH发送了一条消息以帮助改善此问题。Python文档也可以改进。
— smci

1
结合Python 3.8 的:= walrus运算符,您将获得称为@:=棘手的rose运算符。(或者在日本,它被称为猫王-海象运营商。)
— 鲍勃·斯坦

Answers:


185

从该 文档:

的@(在)操作者意图被用于矩阵乘法。没有内置的Python类型实现此运算符。

该@运算符是在Python 3.5中引入的。@=正如您所期望的那样,是矩阵乘法,后跟赋值。它们映射到__matmul__,__rmatmul__或__imatmul__类似于如何+和+=映射__add__,__radd__或__iadd__。

在PEP 465中详细讨论了操作员及其背后的原理。


12
这就解释了为什么它是最新版本的tokenizer.py,而不是3.4 docs。
— Octavia Togami,2014年


这与Python装饰器有冲突吗?这不是在Python 2.n中实现的,对吧?
— frankliuao

4
这不会与装饰器冲突,因为装饰器永远不能在表达式之前,并且二进制运算符必须始终在表达式之前。
— 2008年

58

@=和@是Python 3.5中引入的用于执行矩阵乘法的新运算符。它们的目的是澄清迄今为止​​与运算符之间存在的混淆,该运算符*根据该特定库/代码中采用的约定用于元素方式乘法或矩阵乘法。结果,将来,运营商*只能用于按元素乘法。

如PEP0465中所述,引入了两个运算符:

  • 一个新的二进制运算符A @ B,与A * B
  • 就地版本A @= B,与A *= B

矩阵乘法与按元素乘法

为了快速突出区别,对于两个矩阵:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • 逐元素乘法将产生:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
  • 矩阵乘法将产生:

    A @ B  =  [[1 * 11 + 2 * 13,   1 * 12 + 2 * 14],
               [3 * 11 + 4 * 13,   3 * 12 + 4 * 14]]

在Numpy中使用

到目前为止,Numpy使用以下约定:

@运算符的引入使涉及矩阵乘法的代码更易于阅读。PEP0465举了一个例子:

# Current implementation of matrix multiplications using dot function
S = np.dot((np.dot(H, beta) - r).T,
            np.dot(inv(np.dot(np.dot(H, V), H.T)), np.dot(H, beta) - r))

# Current implementation of matrix multiplications using dot method
S = (H.dot(beta) - r).T.dot(inv(H.dot(V).dot(H.T))).dot(H.dot(beta) - r)

# Using the @ operator instead
S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

显然,最后一种实现更易于阅读和解释为等式。


11
只是为了澄清一下:从您的第一个示例中,我们可以认为@已经实现了list,事实并非如此。
— Conchylicultor

1
@与np.matmul不相关np.dot。两者相似但不相同。
— Acumenus

@ABB,也许您可​​以提供一个示例来阐明细微差别,并确保答案是完整的?
— benjaminmgross

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.