Ad

Python: Why For Loop Is Behaving Weirdly?

- 1 answer

I am just trying to merge two sorted lists into one sorted list. I know it is a simple task and plenty solutions online, but my question is different. Here's my code:

def merge(list1, list2):
    len1 = len(list1)
    len2 = len(list2)

    list3 = []
    pointer = 0

    for i in range(len1):
        if (list1[i] >= list2[pointer]):
            while (pointer < len2 and list1[i] >= list2[pointer]):
                list3.append(list2[pointer])
                pointer += 1
            i -= 1
        else:
            list3.append(list1[i])

    while (pointer < len2):
        list3.append(list2[pointer])
        pointer += 1

    return list3


if __name__ == "__main__":
    print(merge([1, 2, 3, 10, 11, 22], [4, 5, 6, 7, 20, 21, 30]))

I did debugging and I was confused to see that when I decrease the value i by 1, for example from 3 to 2, on the next iteration it goes back to 4. I have no idea why? You can check it by running the code and seeing the result. I just need explanation why that is happening. Thanks

Ad

Answer

I was confused to see that when I decrease the value i by 1, for example from 3 to 2, on the next iteration it goes back to 4. I have no idea why?

Because for i in range(x) means "execute the for body with i assuming the values of 0 through x-1". Assigning a different value to i does not affect its value in the next iteration.

In other words, for i in range(10) is not a translation of C's or JavaScript's for (i = 0; i < 10; i++). Instead, you can think of it as for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. Seen like that, it is clear that changing one value of i will not affect the subsequent value, which is blindly taken out of a pre-generated list. If you need to modify the iteration progress based on changing conditions, you can write the C/JS-style loop explicitly:

i = 0
while i < len1:
   # ... loop body goes here ...
   i += 1

Written like this, modifying i in loop body will affect iteration in the way you expected.

Ad
source: stackoverflow.com
Ad