如何创建一个链接到numpy的赋值运算符(=)的变量?例如,我们可以像这样分配一个相等的add op = numpy.ndarray.__iadd__,然后使用op(initial_var, increment)调用它,这将与initial_var += increment相同。然而,我似乎想不出如何将op绑定到赋值运算符=。
我为什么要这么做?简单地说,为了稍微优化一下,在某些情况下,我们可以通过简单地复制numpy.ndarray项而不是调用__iadd__来避免额外的__add__开销。这将是一种更花哨/更丑陋的方式:
if a:
b = c
else:
b += c发布于 2019-05-20 22:16:12
我建议:
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发布于 2019-05-20 23:12:02
首先,让我们弄清楚为什么你要实现的目标是困难的。以某种方式取代赋值a=b的函数op_assgn(a, b)需要做什么?主要的困难在于它需要知道调用者为参数a传递的对象的名称。事实上,在这个时间点绑定到a的对象是完全不相关的,但这就是op_assgn可用的。因此,如果我们一心想让这个函数正常工作,那么函数将不得不窥视一个帧,找到call语句,以某种方式获得传递的参数,并将一个值绑定到它(函数)作用域之外的名称。这可能是可以做到的,但不能没有相当数量的黑魔法。
因此,也许更明智的做法是不要接触赋值本身,而是在打包之前完成。下面是这个想法的一个简单实现。
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])因此,基本上这就是您想要的(一旦您用b替换了d之后),只是它涉及到更多的类型,并且它的等价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.4474492500303313https://stackoverflow.com/questions/56222410
复制相似问题