0

so im trying to implement selection sort in python.. and im appending the result of each iteration to a list to print at the end.. my code sorts the list of numbers properly but when i append it to the same list at the end it changes all other lists..

def s_sort(numbers):
  alist=[]
  #do actual sorting here and swap numbers/index if neccessary

       alist.append(numbers)
  return alist

def main():
    numbers=[5,7,3]
    print(s_sort(numbers))
main()

the alist returned is [[3,5,7],[3,5,7]] instead of [[3,7,5],[3,5,7]] !!!! somehow when i do the append to alist, the content of alist changes for both lists!

2
  • 1
    You don't have a list of two lists, you have a list of two copies of the same list. Since you've given us a fragment of code that doesn't run and wouldn't return what you said it does if fixed to run, it's hard to explain why your actual code does that. Commented Jan 21, 2014 at 20:59
  • You should see the concept of shallow copy and deep copy of lists in python Commented Jan 21, 2014 at 21:03

3 Answers 3

2

Use a slice to make a copy

newlist = alist[:]

In your case, I guess it's:

alist.append(numbers[:])
Sign up to request clarification or add additional context in comments.

1 Comment

i understand why it was doing that now lol.. making a copy of the list solved it! thanks!
2

I don't see the actual sort that you're doing, but in general:

Lists are mutable. Any change you make to it affects all links to that list. To make a copy of it and break its connection to other references, you need to return alist[:]

def s_sort(numbers):
  alist=[]
  #do actual sorting here and swap numbers/index if neccessary

       alist.append(numbers)
  return alist[:]  # this makes it a copy!

def main():
    numbers=[5,7,3]
    print(s_sort(numbers))
main()

1 Comment

ahh forgot lists were mutable in python :S thnx!
2

Your code doesn't actually do what you say it does. In fact, it doesn't even run. But here's a simple example that does demonstrate the problem you're seeing:

def s_sort(numbers):
    alist=[]
    alist.append(numbers)
    numbers.sort()
    alist.append(numbers)
    return alist

The problem is that alist is not a list of two different lists, it's a list of the same list twice in a row. So, when you modify that one list, of course that one list is modified everywhere it appears—in numbers, and in alist[0], and in alist[1].

The solution is to not add the same list multiple times; instead, add a new one. For example:

def s_sort(numbers):
    alist=[]
    alist.append(numbers[:])
    alist.append(sorted(numbers))
    return alist

Now you've created two brand-new lists—one an exact copy of the original, one a sorted copy—and returned a list of them.

So, instead of returning [[3, 5, 7], [3, 5, 7]] (and also changing numbers to be [3, 5, 7]), it returns [[5, 7, 3], [3, 5, 7]] (and leaves numbers alone).

I have no idea why you expected [3, 7, 5] for the first element, but maybe you're doing some other work to the first element of alist which you didn't show us. In which case, as long as you do that work in a copying rather than mutating way (ala sorted(n) vs. n.sort()) or do it to a copy, everything will be fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.