如何创建链接到numpy
的赋值运算符(=
)的变量?
例如,我们可以分配一个等于op = numpy.ndarray.__iadd__
的等号,然后再使用op(initial_var, increment)
对其进行调用,这将与initial_var += increment
相同。但是,我似乎无法弄清楚如何将op
绑定到赋值运算符=
。
我为什么要这样做?简单地稍微优化一下,在某些情况下,我们可以通过简单地复制__add__
项而不是调用numpy.ndarray
来避免额外的__iadd__
开销。这将是一个更好/更丑陋的方法:
if a:
b = c
else:
b += c
答案 0 :(得分:0)
我建议:
import numpy as np
op = lambda x,y: np.ndarray.__eq__(x, y).all()
# Examples
a = np.array([1,2,3])
b = np.array([1,2,3])
print(op(a, b)) # True
c = np.array([1,2,6])
print(op(a, c)) # False
答案 1 :(得分:0)
首先,让我们弄清楚为什么您要实现的目标很困难。以某种方式代替分配op_assgn(a, b)
的功能a=b
需要做什么?主要困难在于,它将需要知道调用者为参数a
传递的对象的 name 。实际上,此时绑定到a
的对象是完全不相关的,但这是op_assgn
可用的对象。因此,如果我们想让它起作用,那么该函数将不得不窥视一帧,找到调用语句,以某种方式掌握传递的参数,并将值绑定到其(函数的)范围之外的名称。也许可以做到,但要有大量的黑魔法。
因此,最好不要触摸作业本身,而只是在打包之前进行包装。这是这个想法的简单实现。
def op1(b, c):
return c
op2 = np.ndarray.__iadd__
c = np.array((1,2))
b = np.array((0,0))
请注意,我们正在分配一个新变量d
只是为了看清楚到底发生了什么。最终,您将希望分配给b
。
# this is straight-forward
d = op1(b, c)
d is c
# True
d is b
# False
d
# array([1, 2])
# this works because .__iadd__ does the inplace op AND
# returns the modified object
d = op2(b, c)
d is c
# False
d is b
# True
d
# array([1, 2])
因此,基本上,这可以满足您的要求(一旦您将d
替换为b
),除了它需要更多的输入并且等效的if子句类似于
if a:
b = c
else:
b += c
b = b
在最后一行中有一点难看的冗余分配。
请注意,这主要是一个美学问题,因为分配(通过引用完成)很便宜:
def f1():
global c
c.__iadd__(b)
def f2():
global c
c = c.__iadd__(b)
timeit(f1)
# 1.4087995890295133
timeit(f2)
# 1.4474492500303313