0

I would like to get some advice on my problem with the below code. I declared a few global variables (such as shelfDim, a, b, c, d, productList). These global variables were then used as default arguments in my 2 functions (packByLength, packByWidth).

As part of the function packByWidth(), some of the arguments were altered. For instance, I created a new list newDim, which is basically a copy of the productList. The function then modifies this list by swapping a few elements around. The problem is, my global variables then get changed as a result of running this function. Hence, calling packByWidth() once gives the correct answer, but calling it a second time gives me the wrong answer (because the global variables got changed the first time it was called).

I know that for python, when

a=[1,2,3]
b=a
b[0]=2

both a and b will be changed to [2,2,3]. However, i was not expecting this to happen as my list operations were contained inside a function.

Could anyone tell me what is causing this behaviour, and what can be done to prevent this from happening? I would like my global variables to remain unchanged regardless of how many times I run my functions! P.s. I have tried using tuples in my global variables but it has not helped. Thank you!

import numpy as np

# Parameters
shelfDim = [100, 120, 150]
a = [15, 4, 30]
b = [11, 8, 12]
c = [5, 3.5, 18]
d = [23, 6.8, 10]
productList = [a, b, c, d]

# 1 All products to be aligned length-wise (assuming product must be placed upright)
def packByLength(products = productList, shelfDim = shelfDim):
    usableProdSpace =list(shelfDim)
    usableProdSpace[0] = usableProdSpace[0]/len(products)
    totalQty = []
    for product in products:
        packableQty = []
        for dim in range(3):
            packableQty.append(usableProdSpace[dim]//product[dim])
        totalQty.append(packableQty)

    return totalQty


# 2 All products to be aligned width-wise (assuming product must be placed upright)
def packByWidth(products = productList, shelfDim = shelfDim):
    swap = None
    newDim = list(products)
    for product in newDim:
        swap = product[0]
        product[0] = product[1]
        product[1] = swap
        print ('products', products)
        print ('newDim', newDim)
    totalQty = packByLength(products = newDim)

    return totalQty
ufnan
  • 1
  • Unrelated to your problem, but Python can swap two variables without an intermediary variable: `product[0], product[1] = product[1], product[0]` – Kevin Jan 10 '19 at 18:34
  • You're a little confused by how values/objects are passed between functions. Read [this answer](https://stackoverflow.com/a/986145/6779307) for a better understanding of how it works. – Patrick Haugh Jan 10 '19 at 18:36
  • @PatrickHaugh thanks for the link! Do you mind clarifying on what is meant by the parameter being passed as a reference vs a copy? I understand the difference between the two, I am not sure how python decides which should be the case. From what I can tell, both functions in the example modify the list that was passed in. Also, for my code, wouldn’t it have helped that I assigned list2 = list(list1) and made the changes to list2? Thanks again! – ufnan Jan 11 '19 at 19:54
  • @Kevin thanks! Somehow I didn’t think of swapping them that way – ufnan Jan 11 '19 at 19:57
  • Python never uses a copy. Sometimes it seems that way because the data type is immutable, but immutable types behave that way under all contexts. If you pass a `tuple` to a function, the function uses the same tuple object. It can't change the tuple because the tuple is immutable. – Patrick Haugh Jan 11 '19 at 20:27

0 Answers0