help?? on functions

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon May 27 01:48:34 EDT 2013


On Sun, 26 May 2013 21:48:34 -0700, lokeshkoppaka wrote:

> def shuffle(input, i, j):
>     pass
>     input = input[i:j+1] +input[0:i] + input[j+1:]

"pass" does nothing. Take it out.



> def test_shuffle():
>     input = [1, 2, 3, 4, 5, 6]
>     shuffle(input, 1, 2)
>     assert [2, 3, 1, 4, 5, 6] == input
> 
> 
> i had done the above code but the problem is i had manipulated the
> "input" in function shuffle(input, i, j) but once i get back to the
> test_shuffle() function again the variable "input" does not reflect the
> changes made in shuffle(input, i, j) why ,please can any one describe
> why . and help how to reflect that change to the variable "input".

The line of code:

    input = input[i:j+1] +input[0:i] + input[j+1:]


takes the input list, makes three slices from that list, creates a new 
list, and then reassigns the LOCAL variable "input". This does not touch 
the variable on the outside of the function.

This will be more clear if you use different names:

# Outside the function.
mylist = [1, 2, 3, 4, 5, 6]
shuffle(mylist, 1, 2)


Inside the function "shuffle", "input" is a local variable, and when you 
reassign to it, the variable "mylist" on the outside is not changed. Try 
this small function to see what I mean:

def demo(input):
    print('local variable, before:', input)
    input = 100
    print('local variable, after:', input)
    print('non-local variable', mylist)


mylist = [1, 2, 3, 4, 5, 6]
demo(mylist)



So, what can you do to fix this? You have two choices:


1) You can return the shuffled list. Add this line to the end of your 
shuffle function:

    return input


and then inside the test function, do this:

def test_shuffle():
    input = [1, 2, 3, 4, 5, 6]
    input = shuffle(input, 1, 2)
    assert [2, 3, 1, 4, 5, 6] == input


2) You can modify the input list in place.

In this case, instead of reassigning the local variable "input" with the 
new list, you simply tell Python to stuff the new list inside the 
original list. You do that with a slice:


    input[:] = input[i:j+1] + input[0:i] + input[j+1:]


That's a small difference from what you wrote, just three characters [:], 
but it makes a big difference in the effect. Instead of reassigning the 
local variable to the new list, it takes the existing list, and replaces 
each value inside it with the values taken from the new list. For example:


py> mylist = [100, 200, 300, 400, 500, 600]
py> mylist[3:5] = ['A', 'B', 'C']
py> mylist
[100, 200, 300, 'A', 'B', 'C', 600]

py> mylist[1:] = [99, 98, 97]
py> mylist
[100, 99, 98, 97]


Any questions?


-- 
Steven



More information about the Python-list mailing list