Using for loop to iterate two variables together - python

How do I go about doing something like this?
Say I have an array x = np.array([1,2,3,4,5]) of length 5,
for i,j in range(len(x)):
I want i and j to increment together.
This is throwing me an error message:
TypeError Traceback (most recent call last)
<ipython-input-4-37d0ddc3decf> in <module>()
----> 1 for i,j in range(len(x)):
2 print i,j
3
TypeError: only length-1 arrays can be converted to Python scalars
The reason I need this is because I have to use it in a condition inside the for loop. Like say, y[i][j] and I want this to be 0,0 then 1,1 and so on.

Why do you need j in the first place? If j is always equal to i, just use i. No need for a second variable.

Edited answer
OP says
The reason I need this is because I have to use it in a condition inside the for loop. Like say, y[i][j] and I want this to be 0,0 then 1,1 and so on.
In that case, you could simply use:
y[i][i]
Original answer
I'm not really sure why you would want to do that, you could just set it in the first line of the for loop:
for i in range(len(x)):
j = i
... #rest of the code follows
You could also use enumerate, as pointed in comments by #Julien, like below (but IMO, the earlier method is better):
>>> for i, j in enumerate(xrange(len(x))):
... print i, j
...
0 0
1 1
2 2

You could try this:
for i, j in zip(range(len(x)), range(len(x))):
print i, j
So the question is about how to iterate two variables, not why ;-)

Related

How to make last element in python for loop increment one last time

in Python:
ele = 0
for ele in range(0,4):
print('-')
print(ele)
I realized that this will print 3 instead of 4 in the end, which is different from C-style for loop. is while the option to achieve C-style behavior?
Try else. Statements under else will be executed exactly once after the code gets out of the loop.
for ele in range(0,4):
print('-')
else:
ele=ele+1
print(ele)
Output:
-
-
-
-
4
You can add an independent variable to count the loop iterations with enumerate():
N = 4
items = range(0, N)
i = 0
for i, x in enumerate(items, 1):
print(i, ":", x)
print("number of loop iterations done:", i)
You should make sure to reset the value before the loop, as it is not set to zero, when the loop did not iterate even once.
For reference:
https://docs.python.org/3/library/functions.html#enumerate
In python the range function works differently, if you want to print something N times try this:
ele = 0
for i in range(N):
print("-")
print(ele)
Also is not the only approach you could take for printing, you can also:
print("-\n"*(N-1) + "-" + ele)
The range() function works in different ways:
range(N) which means a list from 0 to N-1, i.e, a list containing N elements
range(A,B) which means a list from integer A to integer B
range(A,B,k) which means a list starting from integer A ending before B and with increments k
You can also refer to the official documents:
docs.python.org/3/library/functions.html#func-range
Hope this helps :D!
ele = 0
for ele in range(0,4):
print('-')
print(ele+1)
for ele in range(param1, param2), it means param1 <= ele < param2
if you want to get the value of param2, you might change the value bigger than param2.
A for with a range is roughly equivalent to a for on a list, i.e. your loop could also be written as:
for ele in [0, 1, 2, 3]:
print('-')
If you want ele to be equal to the number of loops after executing the for instruction, you could also write:
for ele in [1, 2, 3, 4]:
print('-')
which can be rewritten using range as:
for ele in range(1, 5):
print('-')
since range goes from the first parameter to the number immediately before the second parameter.

How to update a variable inside the while loop and see the results?

I want to use a for loop to define a range and I would like to use a while loop to check a condition for every value inside this for loop and give me the results for different values of c, but unfortunately, my algorithm doesn't work and I don't know what my mistake is.
j=0
jl=[]
c=np.linspace(0,20,num=20)
for a in range(0,len(c)):
while j<5:
j=c[a]+2
jl.append(j)
The result I am looking for is it puts different values of c inside the while loop and calculate j and check if it is bigger than 5 or not. if yes, it appends it to jl. Totally, I want to define a range with for loop with index and also check each value of this range inside while loop and get the results for j.
so expected results are j with values smaller than 5 (c[a]+2<5) and store the values of j in jl
There is one problem in your code:
j=0
"While loop" never runs because his condition is j>5. Correct that and tell us if it works.
Please double check if the following suggested solution covers all of your requirements. In any case I think List Comprehensions (e.g. compare section 5.1.3.) can help you.
c=np.linspace(0,20,num=20)
ls = [x+2 for x in c if((x+2)<5)]
print(ls)
Will result in the following output:
[2.0, 3.052631578947368, 4.105263157894736]
If you want to do more complex data manipulation, you can also do this with the help of functions, e.g. like:
def someManipulation(x):
return x+2
ls = [someManipulation(x) for x in c if(someManipulation(x)<5)]
Your algorithm doesn't work because
while j<5:
j=c[a]+2
is an infinite loop for j = 0, a = 0.
What you probably wanted to write was:
for x in c:
j = x + 2
if j < 5:
jl.append(j)
Still, the list comprehension version in the other answer does exactly the same, but better.

Output of for loop code snippet in python

i, j, k, u = 0, 5, 1, 3
for l in range(i, j, k):
if l == u:
print(l)
u = 8
i = 12
j = 7
k = -1
else:
print(l)
OUTPUT is :
0
1
2
3
4
Why do we get this output?
When Python first encounters the for loop, it builds the range object you requested: range(0, 5, 1). Once constructed, it controls the loop, and will not be reevaluated. Changing the variable values during loop execution will not change the loop operation.
This means that, as far as the loop (or a sufficient optimizer) is concerned, your code looks like this:
i,j,k,u=0,5,1,3
for l in range(i,j,k) :
print(l)
u=8
i=12
j=7
k=-1
Not sure what output you expect. But since you change the values of the parameters used for generating the range I assume that you expect the output to be longer. At that point the list is already generated however and will not be affected.
In order to achieve the possibility of increasing the loop range during the looping I suggest you avoid the range function and consider using while instead of for.
https://docs.python.org/3/tutorial/controlflow.html
Edit: Prune was both faster and better than me.

Nested list sorting in Python

This is a question of nested loop where I have to find the names of students in alphabetical order with 2nd lowest marks.
I am getting following error:
Traceback (most recent call last):
File "solution.py", line 12, in <module>
if (l[i][0]==l[0][0]):
IndexError: list index out of range
Following is my complete code.
l=list()
p=list()
q=list()
for i in range (int(raw_input())):
p=[raw_input(),int(raw_input())]
p.reverse()
l.append(p)
l.sort()
print len(l)
for i in range(0,len(l)):
print "i= ",i
if (l[i][0]==l[0][0]):
l.remove(l[i])
print l
for i in range(0,len(l)):
if (l[i][0]==l[0][0]):
q.append(l[i][1])
q.sort()
for i in range(0,len(q)):
print q[i]
I have even printed the index which shows the values are in range. Please run the function to find the following output:
4
i= 0
i= 1
i= 2
i= 3
I will happy if I get any better method from my the community ,But my main concern is the error I am getting "Index Out of Range" .It doesn't seem right here
The problem is that you are removing items from a loop. The thumb rule is that you shall never remove items from a list while iterating over it.
I don't really understand your code right now, but you can just change the way you are doing the first loop and apply the same logic for the next ones, at least you will have what you want.
The idea here is that with the while statement, after each iteration, you will have another verification of the size of the list. Meanwhile with the for loop, only at the first time, since range will return a list and the for loop will just iterate over the list which was already created.
l=list()
p=list()
q=list()
for i in range (int(raw_input())):
p=[raw_input(),int(raw_input())]
p.reverse()
l.append(p)
l.sort()
print len(l)
i = 0
while i < len(l):
print "i= ",i
if (l[i][0]==l[0][0]):
l.remove(l[i])
i += 1
print l
You are using remove, because of that l, in some moment, have less elements than you expect.

python : list index out of range error while iteratively popping elements

I have written a simple python program
l=[1,2,3,0,0,1]
for i in range(0,len(l)):
if l[i]==0:
l.pop(i)
This gives me error 'list index out of range' on line if l[i]==0:
After debugging I could figure out that i is getting incremented and list is getting reduced.
However, I have loop termination condition i < len(l). Then why I am getting such error?
You are reducing the length of your list l as you iterate over it, so as you approach the end of your indices in the range statement, some of those indices are no longer valid.
It looks like what you want to do is:
l = [x for x in l if x != 0]
which will return a copy of l without any of the elements that were zero (that operation is called a list comprehension, by the way). You could even shorten that last part to just if x, since non-zero numbers evaluate to True.
There is no such thing as a loop termination condition of i < len(l), in the way you've written the code, because len(l) is precalculated before the loop, not re-evaluated on each iteration. You could write it in such a way, however:
i = 0
while i < len(l):
if l[i] == 0:
l.pop(i)
else:
i += 1
The expression len(l) is evaluated only one time, at the moment the range() builtin is evaluated. The range object constructed at that time does not change; it can't possibly know anything about the object l.
P.S. l is a lousy name for a value! It looks like the numeral 1, or the capital letter I.
You're changing the size of the list while iterating over it, which is probably not what you want and is the cause of your error.
Edit: As others have answered and commented, list comprehensions are better as a first choice and especially so in response to this question. I offered this as an alternative for that reason, and while not the best answer, it still solves the problem.
So on that note, you could also use filter, which allows you to call a function to evaluate the items in the list you don't want.
Example:
>>> l = [1,2,3,0,0,1]
>>> filter(lambda x: x > 0, l)
[1, 2, 3]
Live and learn. Simple is better, except when you need things to be complex.
What Mark Rushakoff said is true, but if you iterate in the opposite direction, it is possible to remove elements from the list in the for-loop as well. E.g.,
x = [1,2,3,0,0,1]
for i in range(len(x)-1, -1, -1):
if x[i] == 0:
x.pop(i)
It's like a tall building that falls from top to bottom: even if it is in the middle of collapse, you still can "enter" into it and visit yet-to-be-collapsed floors.
I think the best way to solve this problem is:
l = [1, 2, 3, 0, 0, 1]
while 0 in l:
l.remove(0)
Instead of iterating over list I remove 0 until there aren't any 0 in list
List comprehension will lead you to a solution.
But the right way to copy a object in python is using python module copy - Shallow and deep copy operations.
l=[1,2,3,0,0,1]
for i in range(0,len(l)):
if l[i]==0:
l.pop(i)
If instead of this,
import copy
l=[1,2,3,0,0,1]
duplicate_l = copy.copy(l)
for i in range(0,len(l)):
if l[i]==0:
m.remove(i)
l = m
Then, your own code would have worked.
But for optimization, list comprehension is a good solution.
The problem was that you attempted to modify the list you were referencing within the loop that used the list len(). When you remove the item from the list, then the new len() is calculated on the next loop.
For example, after the first run, when you removed (i) using l.pop(i), that happened successfully but on the next loop the length of the list has changed so all index numbers have been shifted. To a certain point the loop attempts to run over a shorted list throwing the error.
Doing this outside the loop works, however it would be better to build and new list by first declaring and empty list before the loop, and later within the loop append everything you want to keep to the new list.
For those of you who may have come to the same problem.
I am using python 3.3.5. The above solution of using while loop did not work for me. Even if i put print (i) after len(l) it gave me an error. I ran the same code in command line (shell)[ window that pops up when we run a function] it runs without error. What i did was calculated len(l) outside the function in main program and passed the length as a parameter. It worked. Python is weird sometimes.
I think most solutions talk here about List Comprehension, but if you'd like to perform in place deletion and keep the space complexity to O(1); The solution is:
i = 0
for j in range(len(arr)):
if (arr[j] != 0):
arr[i] = arr[j]
i +=1
arr = arr[:i]
x=[]
x = [int(i) for i in input().split()]
i = 0
while i < len(x):
print(x[i])
if(x[i]%5)==0:
del x[i]
else:
i += 1
print(*x)
Code:
while True:
n += 1
try:
DATA[n]['message']['text']
except:
key = DATA[n-1]['message']['text']
break
Console :
Traceback (most recent call last):
File "botnet.py", line 82, in <module>
key =DATA[n-1]['message']['text']
IndexError: list index out of range
I recently had a similar problem and I found that I need to decrease the list index by one.
So instead of:
if l[i]==0:
You can try:
if l[i-1]==0:
Because the list indices start at 0 and your range will go just one above that.

Categories