Python OOP __Add__矩阵在一起(循环问题)

时间:2011-03-16 16:47:28

标签: python oop class matrix addition

class Matrix:
  def __init__(self, data):
    self.data = data

  def __repr__(self):
    return repr(self.data)  

  def __add__(self, other):
    data = []

    for j in range(len(self.data)):
        for k in range(len(self.data[0])):
            data.append([self.data[k] + other.data[k]])
        data.append([self.data[j] + other.data[j]])
        data = []

    return Matrix(data)  

x = Matrix([[1,2,3],[2,3,4]])
y = Matrix([[10,10,10],[10,10,10]])
print(x + y,x + x + y)

我能够让矩阵添加1行n列,但是当我尝试通过添加第二个循环来增加所有n个n矩阵时,我得到了这个错误。

Traceback (most recent call last):

  line 24, in <module>
    print(x + y,x + x + y)

  line 15, in __add__
    data.append([self.data[k] + other.data[k]])

IndexError: list index out of range

2 个答案:

答案 0 :(得分:1)

这个怎么样:

class Matrix:
  def __init__(self, data):
    self.data = data

  def __repr__(self):
    return repr(self.data)  

  def __add__(self, other):
    data = []

    for j in range(len(self.data)):
        data.append([])
        for k in range(len(self.data[0])):
            data[j].append(self.data[j][k] + other.data[j][k])

    return Matrix(data)

答案 1 :(得分:0)

您的代码存在一些问题......第一个是加法算法的基本逻辑

data.append([self.data[k] + other.data[k]])

这个陈述非常值得怀疑......数据是一个二维矩阵,但是你在这里用一个索引来访问它。因此,data[k]是一整行并使用+来连接行(可能不是你想要的,对吗?)。可能highBandWidth的解决方案正是您所寻找的。

第二个问题更微妙,而且是关于声明

self.data = data

这个可能是一个问题,因为Python使用所谓的“引用语义”。您的矩阵将使用传递的data参数作为内容但不复制它。它将存储对传递给构造函数的相同data列表对象的引用。 可能这是故意的,但可能不是......这不清楚。如果您从相同数据构建两个矩阵然后在第一个元素中更改单个元素的内容,那么第二个内容的更改是否合适?如果不是这种情况,那么您应该复制data的元素,而不仅仅是使用

分配data成员
self.data = [row[:] for row in data]

或使用standard copy module中的copy.deepcopy

第三个问题是你只使用两个空格进行缩进。这不聪明......在python中工作时,你应该使用4个空格缩进,而不要使用硬标签chracters。请注意,我说这样做(使用两个空格)并不聪明,不是你不聪明,所以请不要亲自接受(我甚至在使用python时自己做了同样的愚蠢错误)。如果你真的想要与众不同,那么在python中编写令人惊奇的无错误的软件,而不仅仅是使用错误的缩进或为函数或变量选择坏名称。专注于更高层次的美丽。

最后一个问题是(一旦你真正理解为什么你的代码不起作用)你应该真正阅读python list comprehensions,这个工具如果明智地使用它可以大大简化你的代码。例如,您可以将附加代码变为

return Matrix([[a + b for a, b in zip(my_row, other_row)]
               for my_row, other_row in zip(self.data, other.data)])

对于受过训练的人来说,这比原始代码更容易阅读(而且速度也更快)。