-1

Recently I was trying to implement a matrix using lists in Python. I understand that numpy would be more suitable for the job, but I wanted to try it with lists. Here is the code:

def input_array():                  #Take the list elements as input from user
    array = []
    row = input("Enter the num of rows: ")
    col = input("Enter the num of cols: ")
    for i in range(int(row)):
        arr = []
        for j in range(int(col)):
            a = eval(input("Enter an element: "))
            arr.append(a)
        array.append(arr)
    print(array)
    return array


def print_array(array):             #Print the list as a matrix
    for i in range(len(array)): 
        for j in range(len(array[i])): 
            print(array[i][j], end = " ") 
        print() 


def getRowSum(array):               #To get the sum of rows and print them beside respective rows
    arr = array[:]
    for i in range(len(arr)):
        summ = 0
        for j in arr[i]:
            summ += j
        arr[i].append(summ)
    print_array(arr)


array = input_array()
print_array(array)
getRowSum(array)
print(array)

When I run the program, I am facing an odd issue. As per my knowledge, when I am copying a list using [:], then any change to the duplicate list will not affect the original list. But this is not happening in this case. You will see that when I use print(array) after executing getRowSum(), the list changes even though I worked on a copy of the list in the function.

You would understand it better if you execute the code yourself.
Please tell as to what I am doing wrong and how should I really proceed with it.

Sobhan Bose
  • 114
  • 9
  • 1
    For questions like this, you make it much easier for others if you skip the input function and just hard code the matrix. – klutt Jul 20 '20 at 03:39
  • You are correct that you copy the list using [:], however you have a list of lists. See discussion here: https://stackoverflow.com/questions/19951816/python-changes-to-my-copy-variable-affect-the-original-variable – M-Wi Jul 20 '20 at 03:50

3 Answers3

0
import copy
arr.deepcopy()

The above method might help you.The deepcopy() function will help you to deep copy the list in which the change in the copied list doesn't affect the source list.arr[:] will only shallow copy the list which means it copies only the references of the source list.

Srikeshram
  • 87
  • 1
  • 5
0

Slicing a list does not generate a copy of the list; the arrays array and arr will point to the same memory addresses.

Proceed with the following change to getRowSum:

def getRowSum(array):               #To get the sum of rows and print them beside respective rows
    for i in range(len(array)):
        summ = 0
        for j in array[i]:
            print(j, end=" ")
            summ += j
        print(summ)

This code is different from the code you have suggested but nonetheless seems to have the functionality outlined in the function comment.

Then, the entire code sample would be:

def input_array():                  #Take the list elements as input from user
    array = []
    row = input("Enter the num of rows: ")
    col = input("Enter the num of cols: ")
    for i in range(int(row)):
        arr = []
        for j in range(int(col)):
            a = eval(input("Enter an element: "))
            arr.append(a)
        array.append(arr)
    print(array)
    return array


def print_array(array):             #Print the list as a matrix
    for i in range(len(array)):
        for j in range(len(array[i])):
            print(array[i][j], end = " ")
        print()


def getRowSum(array):               #To get the sum of rows and print them beside respective rows
    for i in range(len(array)):
        summ = 0
        for j in array[i]:
            print(j, end=" ")
            summ += j
        print(summ)


array = input_array()
print_array(array)
getRowSum(array)
print(array)

AnthonyHein
  • 131
  • 4
0

lists are passed by reference and you are mutating the list. If you want to construct a new list use a list comprehension with list concatenation

def input_array():                  #Take the list elements as input from user
    return [[i*j for i in range(5)] for j in range(5)]

array = input_array()
arrays = [row + [sum(row)] for row in input_array()]
print(f"original: {array} \nwith totals:{arrays}")

output

original: [[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12], [0, 4, 8, 12, 16]] 
withtotals:[[0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 10], [0, 2, 4, 6, 8, 20], [0, 3, 6, 9, 12, 30], [0, 4, 8, 12, 16, 40]]
Rob Raymond
  • 29,118
  • 3
  • 14
  • 30