0

I was trying to sort a list using for loops in python. I wrote the code like this.

L=[1,2,3,6,7,9,4]
NL=[]
for i in L:
    NL.append(min(L))
    L.remove(min(L))
    print(NL)

But here the output is [1, 2, 3, 4]. I can't understand why the output is stopping at 4. I am new to coding. It would be helpful if someone could help me with this.

Thomas
  • 174,939
  • 50
  • 355
  • 478
Adithya
  • 35
  • 1
  • 5
  • Heya! Is there a reason you're not using `sorted(L)`? I suspect there is a question under the question here, but as the first answer says your basic issue is that you should not modify a list while looping over it. – Nathaniel Ford Feb 27 '22 at 19:02

1 Answers1

0

You're removing elements from a list while looping over it, which is problematic (if the index of the element you're removing is before your current loop index, the "next element" being shifted back by one won't be visited). As you don't need to work with the index anyways, you can simply loop n times, where n is the number of elements in the list (the length of the list):

L=[1,2,3,6,7,9,4]
NL=[]
for _ in range(len(L)):
     NL.append(min(L))
     L.remove(min(L))
     print(NL)

Side note: The algorithm you've implemented is called "selectionsort" and has quadratic time complexity. You're also emptying the input list. In practice, you should usually be using Python's builtin [...].sort() to sort the input list in place; if you want a sorted copy, you can always call [...].copy() first.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Luatic
  • 8,513
  • 2
  • 13
  • 34
  • In both cases you're not using `i` - essentially you just want to do the remove/append operation `i` times. In that case, you should do `for _ in range(len(L))` rather than `...in L[whatever]`. Further, the second option, going in reverse, doesn't actually do anything different than the first for this reason. – Nathaniel Ford Feb 27 '22 at 19:05
  • @juanpa.arrivillaga because it doesn't have to copy a thing, whereas the other should (barring optimizer magic) have to copy the entire list in O(n) time? – Luatic Feb 27 '22 at 19:05
  • @juanpa.arrivillaga I should just change this to a loop that runs `n` times, just realizing now... – Luatic Feb 27 '22 at 19:07
  • @juanpa.arrivillaga fixed. I jumped at the "looping over list while modifying" pattern and forgot to check the loop body for use of the loop variable. – Luatic Feb 27 '22 at 19:09
  • @juanpa.arrivillaga [Slicing does not copy lists](https://stackoverflow.com/questions/5131538/slicing-a-list-in-python-without-generating-a-copy) – Luatic Feb 27 '22 at 19:13
  • That's not exactly true. The *references* are copied, meaning if you have a list of 100 items a 100 references are copied. If they reference giant objects... those objects remain in-place. However you will still see a performance of 'O(n)` when doing a slice. Longer inputs will linearly increase time required. – Nathaniel Ford Feb 27 '22 at 19:16