我目前正在代码大战中练习python
,这里有一个提示:
创建一个支持加法、减法、点积和范数的Vector
对象。因此,例如:
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
c = Vector([5, 6, 7, 8])
a.add(b) # should return a new Vector([4, 6, 8])
a.subtract(b) # should return a new Vector([-2, -2, -2])
a.dot(b) # should return 1*3 + 2*4 + 3*5 = 26
a.norm() # should return sqrt(1^2 + 2^2 + 3^2) = sqrt(14)
a.add(c) # raises an exception
我编写了通过一些测试的加法和减法函数。但是,在运行添加函数后,我遇到了覆盖之前的“a”列表值的问题。当我进行减法时,向量
中的“a”值是根据 add 函数的前一个实例计算出的总和。
我怀疑这是因为我运行了这行代码:
返回 self.__class__(self.list)
导致类的实例覆盖自身。
请帮忙,我相信我需要返回该类实例的副本,但不知道该怎么做。
class Vector:
def __init__(self, list):
self.list = list #[1,2]
self.copylist = list
def add(self,Vector):
try:
self.list = self.copylist
#take list from other vector
other = Vector.list
#take each value from other Vector and add it to self.list
for index,item in enumerate(Vector.list,0):
self.list[index] = item + self.list[index]
except:
print("Different size vectors")
#return the instance of a class
return self.__class__(self.list)
def subtract(self,Vector):
self.list = self.copylist
other = Vector.list
print(self.list)
print(other)
for index,item in enumerate(Vector.list,0):
self.list[index] = self.list[index] - item
return self.__class__(self.list)
def dot(self,Vector):
self.list = self.copylist
other = Vector.list
#print(self.list)
#print(other)
running_sum =0
for index,item in enumerate(Vector.list,0):
running_sum = running_sum + item * self.list[index]
#print(running_sum, " ", self.list[index], " ", item)
return running_sum
def norm(self):
running_sum = 0
for item in self.list:
running_sum += item**2
return running_sum ** 0.5
def toString(self):
return str(self.list)
`def equals(self,Vector):
return self.list == Vector.list
以下是一些测试:
a = Vector([1, 2])
b = Vector([3, 4])
test.expect(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
test.expect(a.add(b).equals(Vector([4, 6, 8])))
test.expect(a.subtract(b).equals(Vector([-2, -2, -2]))) #code fails here
test.assert_equals(a.dot(b), 26)
test.assert_equals(a.norm(), 14 ** 0.5)
最佳答案
我认为你让事情变得比需要的更复杂。您根本不应该使用类对象。您应该只使用 Vector 类的实例。我认为您的代码应该如下所示:
class Vector:
def __init__(self, initial_elements):
self.elements = list(initial_elements) # make a copy of the incoming list of elements
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# add the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] += item
# return a new vector object defined by the computed elements
return Vector(r)
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# subtract the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] -= item
# return a new vector object defined by the computed elements
return Vector(r)
def dot(self, other):
running_sum = 0
for index, item in enumerate(other.elements, 0):
running_sum += item * self.elements[index]
return running_sum
def norm(self):
running_sum = 0
for item in self.elements:
running_sum += item ** 2
return running_sum ** 0.5
def toString(self):
return str(self.elements)
def equals(self, other):
return self.elements == other.elements
def test():
a = Vector([1, 2])
b = Vector([3, 4])
print(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
print(a.add(b).equals(Vector([4, 6, 8])))
print(a.subtract(b).equals(Vector([-2, -2, -2])))
print(a.dot(b) == 26)
print(a.norm() == 14 ** 0.5)
test()
结果:
True
True
True
True
True
代码的总体结构是正确的。
需要注意的一件事是,您不应该使用 list
作为变量名称,因为它是 Python 中的类型名称。另外,您不想将 Vector
作为值传递。您希望传递 Vector
和 list
的实例,其名称与这些类型名称不冲突。
我的解决方案假设您希望 Vector 实例是不可变的,因此每个操作都将返回一个新的 Vector 对象。您也可以让它们不是不可变的,例如,add 方法只需将传入向量添加到目标向量中,而不创建新对象。我喜欢让它们保持不变。我最近越来越多地进行这种“函数式”编程,其中对对象方法的调用不会修改目标对象(没有副作用),而只是返回一个新对象。
我喜欢您使用 test
类来进行测试。我选择不处理这个问题,只是打印每个测试比较的结果,看看它们是否都为 True
。我将让您将测试恢复为使用带有 expect
和 assert_equals
方法的测试对象。</p>
更新:这是编写 add
和 subtract
方法的更紧凑的方法:
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] + other.elements[i] for i in range(len(self.elements))])
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] - other.elements[i] for i in range(len(self.elements))])
关于python - 如何返回类实例的副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56512465/