ersanowski
ersanowski

Reputation: 59

How does python understand when we give two comparison operators in while loop?

list1 = [1,2,3,4,5]
list2 = [6,7,8,9,10,11]
new_list = list()

i = 0
while i<5 and i<6:
    new_list.append((list1[i],list2[i]))
    i += 1

print(new_list)

The code works, and the output is:

[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]

However, I just wonder how Python works when we give two greater/smaller options in the while loop. In the case above, I've defined both i<5 and i<6, but how does it work inside and how does the program understand i<5 belongs to list1 and i<6 belongs to list2? When I change the while loop as while i<6: I get IndexError: list index out of range.

Upvotes: 2

Views: 71

Answers (1)

j-i-l
j-i-l

Reputation: 10957

Allow me to make a little correction to your statement: Python does not understand that i<5 should belong only to list1 and i<6 to list2.

In fact what is happening is the following:

  • you define one single variable i when writing i=0
  • in while i<5 and i<6: you combine two comparison operations:
    1. is i smaller than 5
    2. is (the same) i smaller than 6
  • inside the while-loop you use that single variable i as index both for list1 and list2 then you increment i by 1.

When writing only while i<6: what happens is that for i=5 the loop still runs and your code tries to get list1[5] which does not exist, as list1 is of size 5 and thus the last element is accessed with list1[4]. If you simply type list1[5] in the console you will get an IndexError, the exact same error you get when removing the i<5 from your while-condition.


If you want to combine several lists into a single list, python has a built-in function for this: zip() If, like in your case, the lists are of various size and you do not want to loose any elements then, also in this case, python has you covered with the zip_longest() method from the itertools module.

Here is how this would look:


list1 = [1,2,3,4,5]
list2 = [6,7,8,9,10,11]
new_list = [*zip(list1,list2)]  # or list(zip(list1,list2))
print(new_list)
>>> [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]


# without loosing elements:
from itertools import zip_longest
new_list = [*zip_longest(list1,list2)]
print(new_list)
>>> [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (None, 11)]

As you can see, the last element of list2 us missing when using zip. With zip_longest, however, it is still there and the 'missing' element from list1 is completed with None.

Hoped that helped to clarify a few things.

Upvotes: 5

Related Questions