-1

i have a task in hand where i need to sort a n-length list whose items are 0~n-1 without duplicates by repeatedly swapping two items.

i would like to keep swapping arr[0] with the item whose index is arr[0] (i.e. arr[arr[0]]) until arr[0] = 0, then repeatedly do the same to arr[1] through arr[n-1].

for example, if the list is arr=[1,2,0,4,3], i'd first swap arr[0] with arr[arr[0]] (i.e. arr[1]), getting [2,1,0,4,3], then swap arr[0] with arr[arr[0]] again, (this time arr[2]), getting [0,1,2,4,3], then swap arr[3] with arr[4], getting the final result [0,1,2,3,4].

the code is as follows:

while i < len(arr) - 1:
    while arr[i] != i:
        arr[i], arr[arr[i]] = arr[arr[i]], arr[i] # not working
        arr[arr[i]], arr[i] = arr[i], arr[arr[i]] # working

    i += 1

the problem is that when i do arr[i], arr[arr[i]] = arr[arr[i]], arr[i], it does not work (it only makes arr[i] = arr[arr[i]]).

swapping in the opposite order (i.e. arr[arr[i]], arr[i] = arr[i], arr[arr[i]]) works.

any one could explain what was going on in the background and why the first case did not work? thanks.

JoYSword
  • 432
  • 1
  • 3
  • 14
  • why not use `arr[i], arr[-i] = arr[-i], arr[i]`? this will ensure you access the list from the front and back simultaneously – Cut7er Sep 02 '18 at 16:08
  • We have no idea what you mean when you say "it does not work." Do you get an error message? Does it do anything at all? Does it do something other than you expected? Much better to post an actual code example that illustrates your exact problem. – John Gordon Sep 02 '18 at 16:09
  • what should happen in case when `max(arr) >= len(arr)`? – Azat Ibrakov Sep 02 '18 at 16:09
  • Possible duplicate of [Swapping first and last items in a list](https://stackoverflow.com/questions/19666772/swapping-first-and-last-items-in-a-list) and [Multiple assignment and evaluation order in Python](https://stackoverflow.com/questions/8725673/multiple-assignment-and-evaluation-order-in-python) – Austin Sep 02 '18 at 16:12
  • @Cut7er that is not what i'm trying to do. please see edited description. thanks. – JoYSword Sep 02 '18 at 16:37
  • @AzatIbrakov that is not possible in my case. please see edited description. thanks. – JoYSword Sep 02 '18 at 16:38
  • @Austin I don't think this is the same case. My issue is probably related to accessing a data item using another item's value as index (i.e. `arr[arr[idx]]`), while the linked questions are just about multiple assignment, although the answers in the linked questions have somewhat explained the mechanism in the background. – JoYSword Sep 02 '18 at 16:55

1 Answers1

2

This comes from the fact that items in a tuple are evaluated from left to right.

If you do arr[i], arr[arr[i]] = arr[arr[i]], arr[i] then arr[i] gets assigned to a new value first, so that the index arr[i] in arr[arr[i]] would no longer be the same value as it was at the beginning of the statement. When it's the opposite order, this issue then doesn't exist because arr[arr[i]] gets assigned a new value first.

blhsing
  • 91,368
  • 6
  • 71
  • 106
  • So `arr[i] = arr[arr[i]]` and `arr[arr[i]] = arr[i]` are not totally independent. Python evaluates `arr[i] = arr[arr[i]` first and this would affect `arr[arr[i]] = arr[i]`, who is evaluated second. Am I understanding right? – JoYSword Sep 02 '18 at 17:11