Reputation: 1313
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
Upvotes: 1
Views: 82
Reputation: 155600
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.
Upvotes: 3
Reputation: 2699
This is because range()
is a generator function. It does not create the list of numbers, as you might expect, but generates a new number as you need it. And, even if it created the list, the numbers would be taken from the list, one after the other, regardless how you modify them. You can think of the result of range()
in a sense as 'read-only'. user4815162342 below is right, you should not confuse it with a C-style loop. More like a Fortran loop, where the number of iterations is computed in advance.
From https://pynative.com/python-range-function/:
Python 3’s range uses the generator. Python 3’s range() will produce value when for loop iteration asked for it. i.e., it The range() doesn’t produce all numbers at once.
Python range() function returns an immutable sequence object of integers, so it is possible to convert range() output to the Python list. Use list class to convert range output to list. Let’s understand this with the following example.
Upvotes: 0
Reputation: 73
You are editing i
inside the for loop that runs on i
. I don't believe it will work the way you intend it.
Also, you can simply merge the lists and sort the outcome with this:
list1 = [1,2,3,10,11,22]
list2 = [4,5,6,7,20,21,30]
list3 = list1 + list2
list3.sort()
print(list3)
Hope this helps.
Upvotes: 0