2017-01-27 2 views
2

Я пытаюсь преобразовать матрицу в Python 3.x без использования numpy. По какой-то причине у меня возникают проблемы с назначением new_matrix[col_num][row_num]. Например, если я создаю новый экземпляр матрицы, такой как test = Matrix([[1,2,3,],[4,5,6],[7,8,9]]), то при первом обращении к внутреннему циклу new_matrix становится [[1,None,None],[1,None,None],[1,None,None]] вместо [[1,None,None],[None,None,None],[None,None,None]]. Я не могу понять, почему это происходит, и почему он присваивает значение всем первым элементам списков.Трансформация матрицы в Python без модулей?

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

    def transpose(self): 
     new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix) 
     row_num = 0 
     for row_num in range(len(self.matrix)): 
      for col_num in range(len(self.matrix[0])): 
       print(new_matrix[col_num][row_num]) 
       print(new_matrix) 

       #assignment assigning more than one variable 

       new_matrix[col_num][row_num] = self.matrix[row_num][col_num] 

       print(new_matrix[col_num][row_num]) 
       print(new_matrix) 

      col_num = 0 
     return new_matrix 
+0

Вы можете использовать 'zip' транспонировать. См. Http://stackoverflow.com/questions/10169919/python-matrix-transpose-and-zip. – kennytm

ответ

2
new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix) 

должен быть заменен

new_matrix = [[None for j in self.matrix[0]] for i in self.matrix] 

Таким образом, все никто не будет "Дифференц".

но более короткий путь, чтобы непосредственно построить результат со списками расширения:

MT= [[M[j][i] for j in range(len(M))] for i in range(len(M[0]))] 
+0

Вам не нужно делать это для внутреннего списка, так как 'None' неизменны. –

+0

@WVO: Вы правы. –

+0

Просто понял, что new_matrix должен быть = [[Нет для j в self.matrix] для i в себе.matrix [0]], а не наоборот, потому что количество строк в новой матрице должно быть числом/столбцов/в исходной матрице. Кроме этого, спасибо! – gridproquo

1

Вот подсказка:

In [9]: arr = [[None] * 2] * 3 

In [10]: arr 
Out[10]: [[None, None], [None, None], [None, None]] 

In [11]: arr[1][1] = 2 

In [12]: arr 
Out[12]: [[None, 2], [None, 2], [None, 2]] 

Вы видите проблему?

Репликация списка (* operator) повторяет тот же объект вложенного списка в содержащем списке. Вместо этого вы должны создавать новый список каждый раз.

2

Это потому, что вы строите newmatrix с:

new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix) 

Если вы:

<array-expr> * number 

вы не копировать этот список, вы скопировать ссылку. Так это значит, что когда вы манипулируете newmatrix[0] вы также манипулировать newmatrix[1] и т.д.

Вы должны решить его список-понимания:

new_matrix = [[None] * len(self.matrix[0]) for _ in range(len(self.matrix))] 

Поскольку здесь вы на самом деле построить новый список для каждой строки.

Так алгоритм должен выглядеть:

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

    def transpose(self): 
     new_matrix = [[None] * len(self.matrix[0]) for _ in range(len(self.matrix))] 
     row_num = 0 
     for row_num in range(len(self.matrix)): 
      for col_num in range(len(self.matrix[0])): 
       print(new_matrix[col_num][row_num]) 
       print(new_matrix) 

       #assignment assigning more than one variable 

       new_matrix[col_num][row_num] = self.matrix[row_num][col_num] 

       print(new_matrix[col_num][row_num]) 
       print(new_matrix) 

      col_num = 0 
     return new_matrix
+0

код с подсветкой (... хорошо жирный шрифт)! я впечатлен! –

+0

@hiroprotagonist: нам понадобилось некоторое время, чтобы понять, как это сделать, но, как и Python, все так просто на SO. Это похоже на «импорт антигравитации»: p –

+2

Я сохраню ваш трюк в уме; может пригодиться. Спасибо за это! по поводу 'import antigravity': я люблю' xkcd-style' для matplotlib для рисования ручных волнистых графиков ... –

Смежные вопросы