Lesson-3.3
Nested loops
Consider the following problem:
Find the number of ordered pairs of positive integers whose product is 100. Note that order matters: (2, 50) and (50, 2) are two different pairs.
Solution
The code given above is an example of a nested loop. Lines 2-5 form the outer loop while lines 3-5 form the inner-loop. There are multiple levels of indentation here. Line-3 is the beginning of a new for
loop, so line 4 is indented with respect to line 3. As line 4 is an if statement, line 5 is indented with respect to line 4.
This problem could have been solved without using a nested loop. The nested loop is not an efficient solution. It is left as an exercise to the reader to come up with a more efficient solution to this problem. Let us look at one more problem:
Find the number of prime numbers less than \(n\), where \(n\) is some positive integer.
Solution
The basic idea behind the solution is as follows:
- The outer for loop goes through each element in the sequence \(2, 3, ..., n\).
i
is the loop variable for this sequence. - We begin with the guess that
i
is prime. In code, we do this by settingflag
to beTrue
. - Now, we go through all potential divisors of
i
. This is represented by the sequence \(2, 3, ..., i - 1\). Variablej
is the loop variable for this sequence. Notice how the sequence for the inner loop is dependent oni
, the loop variable for the outer loop. - If
j
dividesi
, theni
cannot be a prime. We correct our initial assumption by updatingflag
toFalse
whenever this happens. As we know thati
is not prime, there is no use of continuing with the inner-loop, so we break out of it. - If
j
doesn't dividei
for anyj
in this sequence, theni
is a prime. In such a situation, our initial assumption is right, andflag
staysTrue
. - Once we are outside the inner-loop, we check if
flag
isTrue
. if that is the case, then we increment count as we have hit upon a prime number.
Some important points regarding nested loops:
- Nesting is not restricted to
for
loops. Any one of the following combinations is possible: for
insidefor
for
insidewhile
while
insidewhile
while
insidefor
- Multiple levels of nesting is possible.
while
versus for
for
loops are typically used in situations where the number of iterations can be quantified, whereas while
loops are used in situations where the number of iterations cannot be quantified exactly. This doesn't mean that the number of iterations in a for
loop is always constant. For example:
In the code given above, the number of iterations will keep varying every time the code is run with a different input. But given the knowledge of the input, the number of iterations is fixed. On the other hand, consider the following example:
The number of iterations in the above code can be determined only after it terminates. There is no way of quantifying the number of iterations as an explicit function of user input.
print: end
, sep
end
Consider the following problem:
Accept a positive integer n
as input and print all the numbers from 1 to n in a single line separated by commas.
For a given value of n
, say n
= 9, we want the output to be:
The following solution won't work:
For n
= 9, this will give the following output:
Thankfully, the print function provides a way to solve this problem:
For n
= 9, this will give the required output:
Whenever we use the print()
function, it prints the expression passed to it and immediately follows it up by printing a newline. This is the default behaviour of print()
. It can be altered by using a special argument called end
. The default value of end
is set to the newline character. So, whenever the end argument is not explicitly specified in the print function, a newline is appended to the input expression by default. In the code given above, by setting end
to be a comma, we are forcing the print()
function to insert a comma instead of a newline at the end of the expression passed to it. It is called end
because it is added at the end. To get a better picture, consider the following code:
This output is:
Even though nothing is being passed to the print function in the first line of code, the first line in the output is a newline because the default value of end
is a newline character ('\n'
). No expression is passed as input to print in the second line of code as well, but end
is set to ,
. So, only a comma is printed. Notice that line 3 of the code is printed in line 2 of the output. This is because end
was set to ,
instead of the newline character in line 2 of the code.
sep
If multiple expressions are passed to the print()
function, it prints all of them in the same line, by adding a space between adjacent expressions. For example:
The output is:
What if we do not want the space or if want some other separator? This can be done using sep
:
The output is:
We could also have an empty string as the separator:
The output will then be:
end
and sep
Let us look at one final example that makes use of both end
and sep
:
Accept a positive integer n
, which is also a multiple of 3, as input and print the following pattern:
For n = 9
, we would like to print:
Solution
Notice that the for
loop iterates in steps of 3 starting from 1. To print the comma separated triplet i,i + 1,i + 2
, sep
is set to ,
. After printing each triplet, the symbol |
needs to be printed. This is achieved by setting end
to be equal to |
. Line 2 makes sure that the symbol |
is present at the beginning of the pattern. The last print()
statement outside the loop is there so that the prompt can move to the next line on the console once the pattern has been printed. You can try removing the last line and see how that changes the output on the console.