Search code examples
pythonarrayspython-3.xlistoperator-precedence

Swapping list elements in python where the expressions contain function calls


if arr = [4,3,2,1] and i want to swap the first value with the minimum of the array , if am using this on python

arr[0] , arr[arr.index(min(arr))] = min(arr) , arr[0] 
#or   
arr[0] , arr[arr.index(min(arr))] = arr[arr.index(min(arr))] , arr[0]

they are not working but if i do this

b = arr.index(min(arr))  
#and then  
arr[0] , arr[b] = arr[b] , arr[0]

this works fine. Can anyone explain why ?


Solution

  • It has to do with the order of the operations.

    We can subclass lists to instrument them to show what they're doing.

    class TracingList(list):
        def __getitem__(self, key):
            value = super().__getitem__(key)
            print(self, "reading", key, "=", value)
            return value
    
        def __setitem__(self, key, value):
            print(self, "writing", key, "=", value)
            super().__setitem__(key, value)
    
        def index(self, value):
            index = super().index(value)
            print(self, "finding index of", value, "=", index)
            return index
    
    
    arr = TracingList([4, 3, 2, 1])
    arr[0], arr[arr.index(min(arr))] = min(arr), arr[0]
    print(arr)
    print("===")
    
    arr = TracingList([4, 3, 2, 1])
    arr[0], arr[arr.index(min(arr))] = arr[arr.index(min(arr))], arr[0]
    print(arr)
    print("===")
    
    arr = TracingList([4, 3, 2, 1])
    b = arr.index(min(arr))
    arr[0], arr[b] = arr[b], arr[0]
    print(arr)
    

    prints out

    [4, 3, 2, 1] reading 0 = 4
    [4, 3, 2, 1] writing 0 = 1
    [1, 3, 2, 1] finding index of 1 = 0
    [1, 3, 2, 1] writing 0 = 4
    [4, 3, 2, 1]
    ===
    [4, 3, 2, 1] finding index of 1 = 3
    [4, 3, 2, 1] reading 3 = 1
    [4, 3, 2, 1] reading 0 = 4
    [4, 3, 2, 1] writing 0 = 1
    [1, 3, 2, 1] finding index of 1 = 0
    [1, 3, 2, 1] writing 0 = 4
    [4, 3, 2, 1]
    ===
    [4, 3, 2, 1] finding index of 1 = 3
    [4, 3, 2, 1] reading 3 = 1
    [4, 3, 2, 1] reading 0 = 4
    [4, 3, 2, 1] writing 0 = 1
    [1, 3, 2, 1] writing 3 = 4
    [1, 3, 2, 4]