1

I'm trying to recreate a stupid idea called sleep sort, however the output is far from expected.

I am expecting

0
1
2
3
5

However I get

0
5
5
5
5

...which is wierd because the thread does: sleep for (item) seconds and then print that item.

Here's my code

import threading
import time

def sleepSort(lst):
    for item in lst:
        threading.Thread(target = lambda: (
            time.sleep(item),
            print(item)
        )).start()

sleepSort([3, 0, 2, 1, 5])

Is there something wrong with my code? Thank you very much in advance!

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
kairo
  • 15
  • 3
  • It's not quite clear to me where the sorting logic happens in your method. – anddt Feb 28 '21 at 15:40
  • @anddt Each item in the list has its own thread where it sleeps for (item) seconds. The largest number sleeps for the longest amount of time and gets printed last, smallest number is printed first. – kairo Feb 28 '21 at 15:53
  • This is essentially radix sort with an arbitrarily large radix (determined lazily). – Karl Knechtel Aug 19 '22 at 09:40

1 Answers1

5

It's typical behavior for many languages and caused by "late binding". You should pass argument explicitly to avoid this and also google something like "python late binding".

def sleepSort(lst):
    for item in lst:
        threading.Thread(target = lambda item: (
            time.sleep(item),
            print(item)
        ), args=(item, )).start()
NobbyNobbs
  • 1,341
  • 1
  • 11
  • 17
  • This worked too! A few seconds ago I figured out maybe it's because after the time.sleep(item), whatever (item)'s value in the for loop is, gets printed out. I added "temp = item" inside the thread and it works, this one too. Thank you, first time I've heard about late bindings, feels great to think that may be the cause and someone else confirming it. – kairo Feb 28 '21 at 15:51
  • can you also explain why `0` comes first and then the `5` ? if it is late binding then why is it not either all `0` or all `5`? – python_user Feb 28 '21 at 16:09
  • @python_user I suppose because of `sleep(0)` this thread has time to be executed with the same `item` value it was started. – NobbyNobbs Feb 28 '21 at 16:17
  • that makes sense, thanks – python_user Feb 28 '21 at 16:20