List index out of range, apparently nothing wrong - python

transposta = []
nova_linha = []
for i in range (len(matriz)):
for j in range(len(matriz[i])):
nova_linha.append(matriz[i][j])
i+=1
transposta.append(nova_linha)
j+=1
nova_linha = []
return transposta
I am getting the list index out of range error in line nova_linha.append(matriz[i][j])
why is this happening?

This would work fine:
for i in range (len(matriz)):
for j in range(len(matriz[i])):
nova_linha.append(matriz[i][j])
transposta.append(nova_linha)
nova_linha = []
However, you added in lines that do i += 1 and j += 1. A for loop over a range already takes care of that for you.
Normally, that would be as harmless as it is useless, because your change would just get thrown away the next time through the loop—but you also got them backward. So now, each time through the inner loop, you increment i, and pretty quickly you run off the bottom of the matrix.

Related

iterating over a changeable iterator in every iteration

I am trying to implement the code below, and I'm getting an error of
"index is out of range". I think I am getting the error because the for loop saved the value of the length of the array, while I changed it inside the loop itself.
I can't figure out how to solve it using a for loop.
I did solve it using a recursive way, but it was computationally expensive and I am dealing with billions of words. BTW, the Comp function only returns a pool if the 2 words having the same sentence, so I believe it doesn't effect.
I am using Python-3, pycharm.
def reg(array,n):
f=open(r"C:\Users\Ali\Desktop\love.txt","w")
length= len(array)
if length==1:
return array
k=0
for item in range (length-1):
k+=1
for j in range(k,length):
if Comp(array[item][0],array[j][0])>=n:
f.write(str("\n"))
f.write(str(array[item][1]))
f.write(str("\n"))
f.write(str(array[j+k ][1]))
array[k+j]=array.pop()
length-=1
break
f.close()
pass
Instead of modifying the array, just keep track of your effective last index and break out when you hit it. Something like (untested)
k = 0
last_index = len(array) - 1
for item in range(length - 1):
if item > last_index:
break
k += 1
# ....
array[k+j] = array[last_index]
last_index -= 1
break

How to force a for loop counter to skip iterations in Python3?

I recently ran into an issue where I was using a for loop somewhat similar to this:
for i in range(lineCount(fileToBeProcessed)):
print(i)
j = doSomeStuff() #returns number of lines in the file to skip
i = i+j
print(i)
print('next_loop')
For a value of j={2,3,1} the output was:
1
3
next_loop
2
5
next_loop
.
.
My desired output:
1
3
next_loop
4
7
next_loop
.
.
Every time the next iteration started, the for loop counter i reset to the original cycle. My question is, is there a way to force the for loop to skip the iterations based on the return value j. I understand and was able to implement something similar with a while loop. However, I was curious as to how or why would Python not allow such manipulation?
It allows manipulations. But a for loop in Python works with a:
for <var> in <iterable>:
# ...
So Python does not attaches a special meaning to range(n) as a for loop: a range(n) is an iterable that iterates from 0 to n (exclusive). At the end of each iteration the next element of the iterable. It furthermore means that once you constructed a range(n), if you alter n, it has no impact on the for loop. This in contrast with for instance Java, where n is evaluated each iteration again.
Therefore you can manipulate the variable, but after the end of the loop, it will be assigned the next value of the loop.
In order to manipulate the variable, you can use a while loop:
i = 0 # initialization
while i < lineCount(fileToBeProcessed): # while loop
print(i)
j = doSomeStuff() #returns number of lines in the file to skip
i = i+j
print(i)
print('next_loop')
i += 1 # increment of the for loop is explicit here
Usually a while loop is considered to be "less safe" since you have to do the increment yourself (for all code paths in the loop). Since it is something one tends to forget, it is easier to write an endless loop.
Assuming that fileToBeProcessed is actually a file-like object, you can iterate directly over the file (i.e. over the lines in that file), or use enumerate(fileToBeProcessed) if you need the line numbers, and call next on that iterator to skip lines.
Like this (not tested):
iterator = enumerate(fileToBeProcessed) # or just iter = fileToBeProcessed
for i, line in iterator:
print(i)
j = doSomeStuff() #returns number of lines in the file to skip
for _ in range(j):
i, line = next(iterator) # advance iterator -> skip lines
print(i)
print('next_loop')
I've edited the code hope it may help
z =0
for i in range(lineCount(fileToBeProcessed)):
if i <= z: #if i is a value that you don't want to be output, then skip loop to next one
continue
print(i)
j = doSomeStuff()
cnt += 1
z = i+j #use a different variable from i since i the iterator value will not be updated
print(z)
print('next_loop')

How do I check every element in an appended text in python

I am doing the Euler project questions and the question I am on right now is least common multiple. Now I can go the simple route and get the factors and then find the number that way, but I want to make my life hard.
This is the code I have so far in Python:
i = 0
j = 0
count = []
for i in range (1,10):
for j in range(1,11):
k = i%j
count.append(k)
print(count)
Now when I print this out I get an array and every time I goes through the loop, the previous information is appended on with it. How can I make it so that the previous information is not appended?
Second once I get that information how can I look at each value in the array and only print out those elements that are equal to 0? I feel like I have to use the all() function but for some reason I just dont get how to use it.
Any and all help is appreciated.
For your first question, you should know the scope of variable. Just define the variable count inside the outer loop and before the inner loop starts.
You can try this if you want nothing but zero elements.
print [element for element in count if element == 0]
If I understand your question right the answer for your question is like this.
i = 0
j = 0
for i in range (1,10):
# Resetting so that count will not have previous values
count = []
for j in range(1,11):
k = i%j
count.append(k)
# printing all the indexes where the value is '0'
print([index for index, item in enumerate(count) if item == 0])
You know your range of extern loop so you can just write your code in this way :
count = []
for i in range (1,10):
for j in range(1,11):
k = i%j
if(i == 9):
count.append(k)
print(count)
print("Without 0:")
print([x for x in count if x is not 0])

Python-Merge sort difficulties

I attempted to implement a merge sort, here is my code:
def mergeSort(array):
result=[]
n=len(array)
if n==1:
result=array
else:
a=round(n/2)
first=mergeSort(array[0:a])
second=mergeSort(array[a:n])
for i in range(len(first)):
for j in range(len(second)):
if first[i]<second[j]:
result.append(first[i])
i=i+1
else:
result.append(second[j])
j=j+1
return result
a=[5,4,1,8,7,6,2,3]
b=mergeSort(a)
print(b)
Unfortunately, the result turns out to be [1]. What is wrong with my function?
A number of things...
Firstly, this is a recursive function, meaning you cannot create a list within the function, as you did here:
result=[]
This will simply reset your list after every recursive call, skewing your results. The easiest thing to do is to alter the list that is passed as a parameter to merge sort.
Your next problem is that you have a for loop within a for loop. This will not work because while the first for loop iterates over first, the second for loop will iterate over second for every increment of i, which is not what you want. What you need is to compare both first and second and extract the minimum value, and then the next minimum value, and so on until you get a sorted list.
So your for loops need to be changed to the following:
while i < len(first) and j < len(second):
Which leads me to final problem in your code. The while loop will exit after one of the conditions are met, meaning either i or j (one or the other) will not have reached len(first) or len(second). In other words, there will be one value in either first or second that is unaccounted for. You need to add this unaccounted value to your sorted list, meaning you must implement this final excerpt at the end of your function:
remaining = first if i < j else second
r = i if remaining == first else j
while r < len(remaining):
array[k] = remaining[r]
r = r + 1
k = k + 1
Here r represents the index value where the previous while loop broke off. The while loop will then iterate through the rest of the remaining values; adding them to the end of your sorted list.
You merge sort should now look as follows:
def mergeSort(array):
if len(array)==1:
return array
else:
a=round(len(array)/2)
first=mergeSort(array[:a])
second=mergeSort(array[a:])
i = 0
j = 0
k = 0
while i < len(first) and j < len(second):
if first[i]<second[j]:
array[k] = first[i]
i=i+1
k=k+1
else:
array[k] = second[j]
j=j+1
k=k+1
remaining = first if i < j else second
r = i if remaining == first else j
while r < len(remaining):
array[k] = remaining[r]
r += 1; k += 1
return array
I tried to not alter your code as much as possible in order to make it easier for you to understand. However, if your difficulty in understanding what I did persists, try de-bugging your merge sort using multiple print statements so that you can follow the function's progress and see where it goes wrong.

returning indices using a while loop

I'm trying to take an input of a list of numbers and return the list of indices in the original list that contain negative values. I also want to use a while loop. Here is my code so far.
def scrollList2(myList):
negativeIndices = []
i = 0
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
return negativeIndices
How to I stop the loop and how do i get the indices to return? Right now when I run it, it runs forever (infinite loop) how do I tell it to stop once it hits the last indices of myList?
When you hit your first non-negative number, the if is never entered again and i never gets incremented again. Put the part where you increment i outside the if block.
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
Assume, the conditional myList[i] < 0 is not true. In that case, i won’t be incremented and nothing else happens either. So you will end up in the next iteration, with the same value of i and the same conditional. Forever, in an endless loop.
You will want to increment i regardless of whether you matched something or not. So you will have to put the increment outside of the if conditional. Furthermore, you want to increment i after appending the index to the list, so you actually append the index you tested, and not the one afterwards:
while i < len(myList):
if myList[i] < 0:
negativeIndices.append(i)
i = i + 1
Also, you would usually use a for loop here. It will automatically take care of giving you all the values of i which you need to index every element in myList. It works like this:
negativeIndices = []
for i in range(len(myList)):
if myList[i] < 0:
negativeIndices.append(i)
range(len(myList)) will give you a sequence of values for every number from zero to the length of the list (not including the length itself). So if your list holds 4 values, you will get the values 0, 1, 2 and 3 for i. So you won’t need to take care of incrementing it on your own.
Another possibility would be enumerate as Foo Bar User mentioned. That function will take a sequence, or list in your case, and will give you both an index and the value at the same time:
negativeIndices = []
for i, value in enumerate(myList):
if value < 0:
negativeIndices.append(i)
As you can see, this completely removes the need to even access the list by its index.
OP wants to use a while loop, so this answer is not exactly on point - but I feel I should point out that many pythonistas will expect something like:
neg_indices = [k for k,v in enumerate(myList) if v < 0]
This is implicit in the other answers, however it might be useful for lurkers and for OP to consider down the road... While certainly does the job as the other answers show, but its 'free' in a list comprehension; plus, there's no chance of an infinite loop here....

Categories