tauhtauhsauce
tauhtauhsauce

Reputation: 117

Outcome of Function - Python

I'm creating a utility program whose functions will be used as part of another program.

This is my function (EDITED):

def push_up (grid):
   new_grid = up_down_swapper(grid)


   new_grid = zero_DR(new_grid) 

   for i in range(4):
     for j in range(3):                
        if new_grid[i][j] == new_grid[i][j+1]:
            new_grid[i][j+1] = (new_grid[i][j])+(new_grid[i][j])
            new_grid[i][j] = 0
        else: 
            pass

new_grid = zero_DR(new_grid)

grid = up_down_swapper(new_grid)
#print(grid) - shows the grid as the expected outcome. But outside of the function it  doesn't change

and here is how it's used:

push.push_up (grid)

As you guys can see it isn't being assigned to a value like

new_grid = push.push_up (grid)

I cannot change the main program ( this is an assignment and this is what I've been told to do.)

My problem is how do I get the function to change the value of the parameter? I'm not sure if I'm making sense but something like this:

def square(x):
    x = x*x

value = 3 
square(value) 
print(value)

This will output 3, but I'm wanting 9. How would I go about doing this?

Here is a pastebin of the main code: http://pastebin.com/NAxWL14h

Upvotes: 0

Views: 978

Answers (2)

glglgl
glglgl

Reputation: 91017

There is a difference between

  • having a name refer to a different value / object and
  • modifying the object a name refers to.

The first one is done with an assignment:

a = []
b = a
b = [3]
print(a) # still prints []

The second one is only possible with mutable objects (e. g., lists are ok, tuples not):

a = []
b = a
b.append(3)
print(a) # prints [3]

When you do a function call, you essentially do the same:

def f(b):
    b = [3]

only changes what b points to inside the function.

However,

def g(b):
    b.append(3)

changes the list object provided by the caller.

Exactly this is the point: the function in your assignment should modify grid in-place. Instead, you assign it a different object, which won't propagate back to the caller.

Upvotes: 0

Rob Watts
Rob Watts

Reputation: 7146

The short answer is that because of how Python passes parameters, you can't do this. For your square example, there is no way to change the value of value without assigning the result of square(value) to it.

However, you don't need to change what grid is pointing to. In part of your code

for i in range(4): #add numbers that are equal  
    for j in range(3,-1,-1):                
        if grid[i][j] == grid[i][j-1]:
            grid[i][j-1] = (grid[i][j])+(grid[i][j])
            grid[i][j] = 0
        else: 
            pass

You are changing the values held within grid. So think about it this way:

>>> list_to_add_to = []
>>> def add_to_list(a_list):
...     a_list.append('test')
...
>>> print(list_to_add_to)
[]
>>> add_to_list(list_to_add_to)
>>> print(list_to_add_to)
['test']

I did not change what list_to_add_to refers to, but I was still able to modify it. This is referred to as "modifying in-place".

So instead of trying to create a new grid and return that result, you have two options:

  1. Modify the contents of grid
  2. Create a new grid (calling it something else like new_grid) and work with that. Then at the end of your function, copy everything from new_grid into grid.

Upvotes: 1

Related Questions