Why does the swapping work one way but not the other?
<p>For this <a href="https://leetcode.com/problems/first-missing-positive/" rel="nofollow">question</a> on leetcode, I attempted to solve with Python 2.7 with the code at the bottom of the post. However, for an input of <code>[2,1]</code>, the function will loop forever. But, if I change the line doing the swap, and switch the variables so the order is the opposite, the swapping will actually work and the function executes correctly.</p>

<p>So currently the code has the swap as: <code>nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]</code>, which doesn't work (this is in the <code>while</code> loop). If I change the order of swapping to <code>nums[nums[i]-1], nums[i]  = nums[i], nums[nums[i]-1]</code>, the swap/assignment does work. Why is that? I looked on SO and it seemed like Python's <code>a,b=b,a</code> swap works by putting both <code>a</code> and <code>b</code> on the stack (evaluating the right side of <code>=</code> first) and then reassigning them <a href="http://stackoverflow.com/questions/21047524/how-does-swapping-of-members-in-the-python-tuples-a-b-b-a-work-internally">(description here)</a>. If that is how it works, then why shouldn't <code>b,a=a,b</code> achieve the same effects?</p>

<p>On Leetcode's online judge, my current (looping forever way) freezes the page. I tried it on my local Python 2.7 environment and it also loops forever. I tested that <code>a,b=b,a</code> is equivalent to <code>b,a=a,b</code> in my environment. So then - why does my code below loop forever when the swap is in one order and work perfectly in the other order?</p>

<pre><code>def firstMissingPositive(nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            if nums[0] != 1:
                return 1
            else:
                return 2
        i = 0
        while i &lt; len(nums):
            if nums[i] &gt; 0 and nums[i] - 1 &lt; len(nums) and nums[i] != nums[nums[i]-1]:
                #Line below does not work
                nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]

                #=&gt;&gt; ??But this works?? # nums[nums[i]-1], nums[i]  = nums[i], nums[nums[i]-1]
            else:
                i += 1

        for i, int in enumerate(nums):
            if int != i + 1:
                return i + 1

        return len(nums) + 1
</code></pre>

<p>The use of <strong>nums[i]-1</strong> as a subscript for <strong>nums</strong> introduces an extra evaluation that isn't in the order you want.  Run a simple test, such as on the list [1, 2, 3, 4, 5, 6, 7] with just a few of these statements, and you'll see the result.</p>

<p>If you handle just one intermediate operation, I think you'll get the semantics you want:</p>

<pre><code>index = nums[i]
nums[i], nums[index-1] = nums[index-1], nums[i]
</code></pre>

python python-2.7