Himanshu Suthar
Himanshu Suthar

Reputation: 487

Why is value to this list changing? I am not trying to change it

I have created a list named "data" which stores lists.

    Grid = [[0, 0, 0, 0], [1, 0, 0, 0], [2, 1, 0, 0], [1, 2, 3, 0]]
data = [[[1, 5, 7, 6, 8], 10, [5, 10], []], [[], 20, [10, 20, 3], []], [[], 4, [1, 11, 2], []], [[], 5, [7, 8, 9], []]]
size = len(Grid)
n_weeks = len(data[0][0])

def return_sch(demand, avail, sr):
    sum_sr =0
    for i in range(len(sr)):
        sum_sr = sum_sr +sr[i]
    avail = avail+sum_sr
    n = len(demand)
    for i in range(n):
        if demand[i]<avail:
            avail = avail - demand[i]
            demand[i] =0
        elif demand[i]>=0:
            demand[i] = demand[i]-avail
            avail =0
    return demand

print(data[0][0])
print(return_sch(data[0][0], data[0][1], data[0][2]))
print(data[0][0])            

For more reference:

data[i] is data of the ith item. 

data[i][0] => demand of ith item
data[i][1] => availability of ith item
data[i][2] => scheduled reciept of ith item
data[i][3] => prouduction schedule

But, why is the value of data[0][0] changing? I don't want to change it.

Please suggest some something. Thank you.

Upvotes: 2

Views: 100

Answers (3)

pneuma
pneuma

Reputation: 977

The values changes because data[0][0] is an array, and you pass it by reference to return_sch function. Inside this function, this array is called demand, and inside this function, you modify demand by writing into its cells. And since demand is just a name for the original array, you modify the original array.

If you don't want the function to change the array, your options are:

  • rewrite the function to create its own array based on demand instead. I'll leave the fun of doing it to yourself :-)
  • just copy the original array. Either copy at call site by passing list(data[0][0]) instead of data[0][0], like such:
print(data[0][0])
print(return_sch(list(data[0][0]), data[0][1], data[0][2]))
print(data[0][0])            
  • Or copy within the function (which is preferable from software engineering perspective) by adding demand = list(demand) at the beginning, like such:
def return_sch(demand, avail, sr):
    demand = list(demand)
    sum_sr = 0
    for i in range(len(sr)):
        sum_sr = sum_sr + sr[i]
    avail = avail + sum_sr
    n = len(demand)
    for i in range(n):
        if demand[i] < avail:
            avail = avail - demand[i]
            demand[i] = 0
        elif demand[i] >= 0:
            demand[i] = demand[i] - avail
            avail = 0
    return demand

Upvotes: 2

Austin
Austin

Reputation: 26039

You are passing a list to function. Since list is a mutable object, you are actually doing a pass by reference. Hence the changes are reflected back to the passed data.

A simple example to illustrate my point:

def list_append(lst):
    lst.append('another_value')

some_lst = ['some_value']
list_append(some_lst)

print(some_lst)
# ['some_value', 'another_value']

This is not true for a tuple, because it is immutable:

def tuple_append(tupl):
    tupl += ('another_value',)

some_tupl = ('some_value',)
tuple_append(some_tupl)

print(some_tupl)
# ('some_value',)

Upvotes: 0

Basya
Basya

Reputation: 1485

This line:

 demand[i] = demand[i]-avail

changes data[0][0].

You pass data[0][0] in to return_schas the first parameter, demand. demand is now a reference to the object that data[0][0] refers to. So when you change demand[i], you are modifying what data refers to.

Upvotes: 0

Related Questions