Don't understand nested For Loop in Python - python

I don't understand how the i in the 2nd for loop of the code below works.
di = [96, 15, 33, 87]
for i in range(len(di)):
total = di[i]
for j in range(i+1,len(di)):
print(i)
0
0
0
1
1
2
Why is the output 0,0,0,1,1,2. How does i in the 2nd for loop get affected from the first loop? Is there some inheritance? Pardon the newbie here.

len(di) is 4. So the loop
for i in range(len(di)):
will repeat 4 times. Because of the way range works (from lower bound, which is 0 by default if not specified, to 1 below the upper bound), i will be 0 in the first repetition, 1 in the second repetition, and so on. To calculate out how many objects range(x, y) generates, in this case, how often for i in range(x, y)will repeat, you can simply do number of repetitions = y - x. So in this case: len(di) - 0 (default lower bound) = 4.
The loop
for j in range(i+1, len(di)):
print(i)
will repeat the print(i) command len(di) - (i + 1) times. Keep in mind, i is defined by the outer loop. So, during the first loop of
for i in range(len(di)):
i equals 0, so the print(i) command will be executed 4 - (0+1) = 3 times - it will print i(=0) 3 times. In the second loop, iequals 1, so it will be printed 2 times, and so on. So here's whats happening, formatted as code for better readability:
First outer loop:
i = 0
total = di[i] = di[0] = 96
--> first inner loop of first outer loop:
j = i + 1 = 1
i is printed -> prints 0
second inner loop of first outer loop:
j = j+1 = 2
i is printed -> prints 0 again
third inner loop of first outer loop:
j = j+1 = 3 --> since len(di) = 4, the upper bound of range(i+1, len(di)) is reached, so this is the last Repetition
i is printed -> prints 0 again
Second outer loop:
i = 1
total = di[1] = 15
--> first inner loop of second outer loop:
j = i+1 = 2
i is printed -> prints 1
second inner loop of second outer loop:
j = i+1 = 3 -> upper bound of range reached, last repetition
i is printed -> prints 1 again
Third outer loop:
i = 2
total = di[2] = 33
--> first inner loop of third outer loop:
j = i+1 = 3 -> upper bound of range is reached, only Repetition
i is printed -> prints 2
Fourth (and final) outer loop:
i = 3 -> upper bound of range(len(di)) reached, last Repetition
total = di[3] = 87
since j = i+1 = 4, the inner loop does not get executed at all (both bounds of range are equal), so 3 doesn't get printed
end of code.

In programming language, a variable is available for usage within a scope. When you start for loop with a new variable then it would be available for usage until you end it.
As you are beginning the journey to learn python, one of the really good practice is to read official document. https://docs.python.org/3/tutorial/controlflow.html

To help your understanding, try this:
di = [96, 15, 33, 87]
for i in range(len(di)):
print("first loop, i =", i)
total = di[i]
for j in range(i+1,len(di)):
print("second loop, j =", j)
print("second loop, i =", i)
The i is the same in both loops. each time the outer loop runs, it then runs the inner loop until the "for" statement is complete.

Related

Getting different values in for loop when using (_) and (i)

I'm new to coding and I am wondering if someone could explain to me why I get different values when using "for i in range ()" compared to "for _ in range ()". When I execute:
for i in range (64):
i = i * 2
print(i)
I get 2,4,6,8,10, etc. But when I run:
i = 1
for _ in range (64):
i = i * 2
print(i)
I get 2,4,8,6,32,64,128, etc. I would expect these values but when I run this with the above code. What's the difference between using (i) and (_)?
In the for i in version, i gets reset to the current step in the range during each iteration step. It's equivalent to:
i = 0
i = i * 2
print(i) # prints 0
i = 1
i = i * 2
print(i) # prints 2
i = 2
i = i * 2
print(i) # prints 4
...
When you using for i in range(...), i doesn't keep any memory of its value from the previous iteration. The range object just returns the next value in the sequence, and this gets assigned to i each time.
But when you use for _ in, you're not assigning the i variable each time. This time it's like:
i = 1
_ = 0
i = i * 2
print(i) # prints 2
_ = 1
i = i * 2
print(i) # prints 4
_ = 2
i = i * 2
print(i) # print 8
...
This time, i keeps its value from the previous iteration, because the range element is being assigned to _ rather than i.
There's nothing special about _, it's an ordinary variable name. But by convention we use this when we need to assign to a variable but aren't going to use it further.
The difference between for i in range(64) and for _ in range(64) is the use of the loop variable.
In for i in range(64), i takes on the values of the numbers in the range from 0 to 63. This means that each time the loop is run, i is updated with the next number in the range.
In for _ in range(64), the loop variable _ is a placeholder that does not receive a value from the range. This is used when you want to run the loop a certain number of times, but you don't need to use the values generated by the range.
In simpler terms, i is used to keep track of the values in the range, while _ is just used to run the loop a certain number of times without using the values generated by the range.

Can anyone explain these python nested loop please

I have doubt in these python nested for loop, that how the inner loop is executing can anyone resolve my problem here
for i in range(1, 4):
print(i)
for j in range(1, i):
print(j)
Basically, your for loops are counting numbers from 1 to the upper limit minus 1.
Your code will run as follows:
Starting with i=1, it will print out a 1 and then j will go from 1 to 0, that is it will take up no values and j won't be printed.
Next, i will become 2, and then j will go from 1 to 2, resulting in the output 1 from j.
This will continue, and the overall output will be:
(i)1
(i)2
(j)1
(i)3
(j)1
(j)2
The stuff in the brackets show which variable is being printed.
For one your code example is poorly formatted.
I am assuming this is how the code is.
for i in range(1, 4):
print(i)
for j in range(1, i):
print(j)
This is a very simple for loop example, I'll go over two iterations that should make it clear.
Let's look at the outer for loop, it goes from 1 to 3 (4 exclusive)
i=1 now, j will go from 1 to i i.e. 1 to 1.
The inner loop will now look as follows:
..
for j in range(1, 1):
print(j)
As range(1, 1), 1 will be exclusive, hence this loop will not run.
So out of Iteration 1:
1 # print(i)
=====
i=2, now, j will go from 1 to i i.e. 1 to 2.
outer loop will print 2, and now inner loop will look like:
..
for j in range(1, 2):
print(j)
This will print 1, as 2 is excluded limit.
Now output will be
2 # outer loop
1 # Inner loop.
On similar retrospection, the last iteration at i=3
Will give output:
3 # outer loop print(i)
1 # inner loop print(j)
2 # inner loop print(j)
Combining all three the final output would be
1 # outer
2 # outer
1 # inner
3 # outer
1 # inner
2 # inner

Nested loop not printing the first element but going to 2nd element?

I have a very simple piece of code but it's driving me nuts to understand the logic.
for a in range(6):
print("\t\t")
for j in range(a):
print(a, end=" ")
The output is:
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
the first value to be printed is supposed to be 0 since the range(6) starts from 0 and a and j wrapped in for loops both are supposedly getting 0 as first element but it starts from 1 instead.
That comes, because the for loop in range 0 will not be executed. You can not execute something if that has to go 0 times. To make it run as you would like to be, you would have to write following code:
for a in range(6):
print("\t\t")
for j in range(a + 1):
print(a, end=" ")
The value of a is the number of iterations of the inner loop. (Note that the question should have the j loop indented, so that it is inside the a loop, in order to get the output shown.)
On the first iteration, a is 0, and then range(0) will give an empty sequence, which give zero iterations when iterating over it. (Specifically a StopIteration will occur the first time a value is fetched.)
On the next iteration of the outer loop, there will be one j value when iterating, and so forth.
So 0 is printed 0 times (i.e. not at all), then 1 is printed once, 2 is printed twice, ... , 5 is printed 5 times.
You are not using the values of j at all, but they will be:
when a is 0: no iterations
when a is 1: j is 0 only
when a is 2: j is 0, 1
... etc, up to ...
when a is 6: j is 0, 1, 2, 3, 4, 5
Note that in fact it is conventional to use a variable name _ for a loop variable whose value you do not use (at least assuming that it not inside a loop already using _). If you adhere to this convention (i.e. use _ instead of j) and also fix the indentation, then your code might look like:
for a in range(6):
print("\t\t")
for _ in range(a):
print(a, end=" ")

Printing j in external loop when no print(j) specified - why?

(Newbie question, please bear with me...)
For the following code:
x = 4
for j in range(x):
for i in range(x):
print(i)
x = 2
Python prints the following:
0
1
2
3
0
1
0
1
0
1
... and I do not understand why it prints the first iteration of 0 1 2 3 when there is no print(j) command, only print(i). What purpose at all do the line "for j in range(x):" and j specifically serve?
This is an example from the book "Introduction to Computation and Programming Using Python" by John Guttag (used in the MIT courses).
The outer loop for j in range(x): is evaluated one time with x=4, it means that the inner loop will be evaluated 4 times with j=0,1,2,3.
You have then to ask yourself what is the value of x when the expression for i in range(x): is evaluated.
At the first evaluation x is 4, the inner loop is executed with 0,1,2,3 for i.
At the second evaluation x is 2, the inner loop is executed with 0,1 for i
For the third and fourth evaluation x is also 2, and the inner loop is executed with 0,1 for i.

Change value of iterator of parent for loop in nested for loop?

So, I am trying to solve competitive programming using Python and came across a problem which required use of nested loops. I used nested for loop and incremented the value of iterator of parent for loop if certain condition is met in the child for loop. But when the child for loop ends, the value of iterator of parent for loop doesn't change.
Example:
for i in range(5):
print "When i = %d" % (i)
for j in range(i+1,5):
print j
if j % 2 == 0:
i = j
Output:
When i = 0
1
2
3
4
When i = 1
2
3
4
....
How to increment the value of I and make the loop run less times, as I want to decrease the CPU time and cycles?
in python, if you wanna change the value of the iterator in a loop, you should use while loop. Your question isn't clear enough about what you want to achieve, but an example would be:
i = 0
while i < 5:
print "When i = %d" % (i)
i+=1
for j in range(i,5):
print j
if j % 2 == 0:
i = j
Your problem isn't clear enough, but if you wanted to change the for loop you should directly consider using the while loop
I may have been incorrect in my assertion of variable scope, but regardless, the for loop follows the looping variable definition independent of how you attempt to define the looping variable within the loop.
Here is an example of what's happening with your script. No matter how you set i, it will still go through the entire range(5).
In [1]: for i in range(5):
print(i)
i=10
print(i)
Out [1]: 0
10
1
10
2
10
3
10
4
10
You need a while loop instead of a for loop, so you can redefine any variable within the loop. If I understood your exact problem correctly, I think you're looking for this:
i = 0 # initialize i
while i<4: # ensure i stops at no more than 4 in the final iteration
print "When i = %d" % i
for j in range(i+1,5):
print j
if j % 2 == 0:
i = j
break # break out of the j loop if this condition is met
else: # iterate i if none of the 'j %...' conditions are met ('break' is not encountered)
i+=1

Categories

Resources