Python , how to convert this iterations into for loop - python

this are the iterations
i = 0
s_array[i].append(f_array[i][i])
s_array[i].append(f_array[i+1][i])
s_array[i].append(f_array[i+2][i])
s_array[i+1].append(f_array[i][i+1])
s_array[i+1].append(f_array[i+1][i+1])
s_array[i+2].append(f_array[i][i+2])
I want to convert this iterations into for loop
for example like this
for i in range(something):
for j in range(something):
s_array[i].append(f_array[j][i])
I tried many trial and errors, but didn't got any solution

The equivalent iterations:
for i in range(3):
for j in range(3 - i):
s_array[i].append(f_array[j][i])
For example:
for i in range(3):
for j in range(3 - i):
print(i,"-->", j, i)
print("")
Output:
0 --> 0 0
0 --> 1 0
0 --> 2 0
1 --> 0 1
1 --> 1 1
2 --> 0 2

Since you are trying to append values to an array using loops, you could try nested for loops as you have indicated. Also, since you are appending fewer values as the iterations continue, you could implement a negative step value for one of the range() functions in the loops so that you iterate fewer times.
Try doing something like this:
for i in range(3):
for j in range(3-i):
s_array[i].append(f_array[j][i])
Hopefully, this should solve your problem.

Related

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.

Three values for a for loop

I would like to have three values increment at different speeds. My overall goal is to emulate this pattern:
0,0, 0
0,1, 1
0,2, 2
1,0, 3
1,1, 4
1,2, 5
2,0, 6
2,1, 7
2,2, 8
The first two numbers are easy. I would solve it like this:
for x in range(3):
for y in range(3):
print(x, y)
>>> 0 0
>>> 0 1
>>> 0 2
>>> 1 0
>>> 1 1
>>> 1 2
>>> 2 0
>>> 2 1
>>> 2 2
This is the pattern that I want.
The question is how do I increment the third number by one each time, while still having the first two numbers increment in the way that they are?
Basically, how can I make the third number increment by one each time the for loop goes?
Since we have all these answers, I will post the most straightforward one
count = 0
for x in range(3):
for y in range(3):
print(x, y, count)
count += 1
You don't need nested loops for this. You can use itertools.product to get your first two numbers, and enumerate to get your last one.
from itertools import product
for i, (u, v) in enumerate(product(range(3), repeat=2)):
print(u, v, i)
output
0 0 0
0 1 1
0 2 2
1 0 3
1 1 4
1 2 5
2 0 6
2 1 7
2 2 8
itertools.product is a very handy function. It basically performs nested loops efficiently, but its main benefit is that they don't look nested, so you don't end up with massively indented code. However, its real strength comes when you don't know how many nested loops you need until runtime.
enumerate is probably even more useful: it lets you iterate over a sequence or any iterable and returns the iterable's items as well as an index number. So whenever you need to loop over a list but you need the list items and their indices as well, it's more efficient to use enumerate to get them both at once, rather than having a loop that uses range to produce the index and then using the index to fetch the list item.
The third number counts how many total iterations you had so far. For each increment in X it gains the total size of Y's loop, and to that you need to add the value of Y:
X_SIZE = 3
Y_SIZE = 3
for x in range(X_SIZE):
for y in range(Y_SIZE):
print(x, y, x * Y_SIZE + y)
single variable. single loop.
for i in range(9):
print(i // 3, i % 3, i)
// is floor division and % is modulus (the remainder, in most cases)
Personally, I like this solution because it plainly explains the underlying pattern, and can therefore be easily altered or extended to other patterns.
Try this:
for x in range(3):
for y in range(3):
print(x, y, x * 3 + y) # Python 3.x
print x, y, x * 3 + y # Python 2.x
Hope this helps.
You can use simply a count variable for this
count = 0
for x in range(3):
for y in range(3):
print(x, y, ' ' ,count) # use ' ' for making exact look what OP asked..lol
count = count + 1
This looks more natural to me :)
x_range = 3
y_range = 3
for x in range( x_range*y_range ):
print(x // x_range, x % x_range, x)
Similar to what cwharris wrote.

Error i not defined in for loop using python

I have one array 'barray' of size 'bsize' and another 'carray' of size 'csize'.
The i loop is for barray and j loop is for carray.
I get an error that i is not defined. I want the loops to go from 0 to bsize - 2 in steps of 3, and 0 to csize - 2 in single steps.
How should I relate the size and array to the for loop?
bsize = 960
csize = 960
barray = bytearray(fi.read())
carray= bytearray(f1.read())
for i in range (bsize-2,i+3):
for j in range (csize-2,j+1):
for i in range (0, bsize - 2, 3): #possibly bsize - 1?
for j in range (csize - 2): # possibly csize - 1?
#do your thing
That will loop through the first one incrementing i by 3 every time, and j by 1.
Look at this tutorial or these docs to learn range, it's really useful!
I'm not sure if you want to go through bsize - 2 or just up to it. If through, use size - 1 to get size - 2.
The reason you're getting an error is that you haven't defined the i you're using in the step. As you can see, python's range isn't like a lot of other languages' for constructs. Once you get used to it, though, it's really flexible and easy to use.
Some examples using simple range:
>>> for i in range(0, 14, 3):
... print i
...
0
3
6
9
12
>>> for i in range(1, 5):
... print i
...
1
2
3
4
>>> for i in range(5):
... print i
...
0
1
2
3
4

Formulation of a recursive solution (variable for loops)

Please consider the below algorithm:
for(j1 = n upto 0)
for(j2 = n-j1 upto 0)
for(j3 = n-j1-j2 upto 0)
.
.
for (jmax = n -j1 - j2 - j_(max-1))
{
count++;
product.append(j1 * j2 ... jmax); // just an example
}
As you can see, some relevant points about the algo snippet above:
I have listed an algorithm with a variable number of for loops.
The result that i calculate at each innermost loop is appended to a list. This list will grow to dimension of 'count'.
Is this problem a suitable candidate for recursion? If yes, i am really not sure how to break the problem up. I am trying to code this up in python, and i do not expect any code from you guys. Just some pointers or examples in the right direction. Thank you.
Here is an initial try for a sample case http://pastebin.com/PiLNTWED
Your algorithm is finding all the m-tuples (m being the max subscript of j from your pseudocode) of non-negative integers that add up to n or less. In Python, the most natural way of expressing that would be with a recursive generator:
def gen_tuples(m, n):
if m == 0:
yield ()
else:
for x in range(n, -1, -1):
for sub_result in gen_tuples(m-1, n-x):
yield (x,)+sub_result
Example output:
>>> for x, y, z in gen_sums(3, 3):
print(x, y, z)
3 0 0
2 1 0
2 0 1
2 0 0
1 2 0
1 1 1
1 1 0
1 0 2
1 0 1
1 0 0
0 3 0
0 2 1
0 2 0
0 1 2
0 1 1
0 1 0
0 0 3
0 0 2
0 0 1
0 0 0
You could also consider using permutations, combinations or product from the itertools module.
If you want all the possible combinations of i, j, k, ... (i.e. nested for loops)
you can use:
for p in product(range(n), repeat=depth):
j1, j2, j3, ... = p # the same as nested for loops
# do stuff here
But beware, the number of iterations in the loop grows exponentially!
the toy example will translate into a kind of tail recursion so, personally, i wouldn't expect a recursive version to be more insightful for code review and maintenance.
however, to get acquainted to the principle, attempt to factor out the invariant parts / common terms from the individual loop and try to identify a pattern (and best prove it afterwards!). you should be able to fix a signature of the recursive procedure to be written. flesh it out with the parts inherent to the loop body/ies (and don't forget the termination condition).
Typically, if you want to transform for loops into recursive calls, you will need to replace the for statements with if statements. For nested loops, you will transform these into function calls.
For practice, start with a dumb translation of the code that works and then attempt to see where you can optimize later.
To give you an idea to try to apply to your situation, I would translate something like this:
results = []
for i in range(n):
results.append(do_stuff(i, n))
to something like this:
results = []
def loop(n, results, i=0):
if i >= n:
return results
results.append(do_stuff(i, n))
i += 1
loop(n, results, i)
there are different ways to handle returning the results list, but you can adapt to your needs.
-- As a response to the excellent listing by Blckgnht -- Consider here the case of n = 2 and max = 3
def simpletest():
'''
I am going to just test the algo listing with assumption
degree n = 2
max = dim(m_p(n-1)) = 3,
so j1 j2 and upto j3 are required for every entry into m_p(degree2)
Lets just print j1,j2,j3 to verify if the function
works in other general version where the number of for loops is not known
'''
n = 2
count = 0
for j1 in range(n, -1, -1):
for j2 in range(n -j1, -1, -1):
j3 = (n-(j1+j2))
count = count + 1
print 'To calculate m_p(%d)[%d], j1,j2,j3 = ' %(n,count), j1, j2, j3
assert(count==6) # just a checkpoint. See P.169 for a proof
print 'No. of entries =', count
The output of this code (and it is correct).
In [54]: %run _myCode/Python/invariant_hack.py
To calculate m_p(2)[1], j1,j2,j3 = 2 0 0
To calculate m_p(2)[2], j1,j2,j3 = 1 1 0
To calculate m_p(2)[3], j1,j2,j3 = 1 0 1
To calculate m_p(2)[4], j1,j2,j3 = 0 2 0
To calculate m_p(2)[5], j1,j2,j3 = 0 1 1
To calculate m_p(2)[6], j1,j2,j3 = 0 0 2
No. of entries = 6

Categories

Resources