IndexError: list index out of range while using nested loops - python-3.x

A = [34,23,1,24,75,33,54,8]
K = 60
solution=[]
for i in range(len(A)):
for j in range(i+1,len(A)):
v=solution[(A[i]+A[j])]
print(v)
Hi, I am trying to get the list with result of individual sums like: 34+23 34+1 34+24 and so on then next 23+1,23+24 and so on.

Your code fails since it's trying to set v to the (A[i]+A[j])th element of solution, which is empty, so that value doesn't exist.
If I understand what you're trying to do, then this should give the desired result.
A = [34,23,1,24,75,33,54,8]
v = [[A[x] + A[i] for i in range(x + 1, len(A))] for x in range(len(A))]

As you can see here,
List index starts from 0 to the (n-1), where n is the len(list).
So A(len(A)) doesn't exist. Which results in the error.
So to fix this replace
len(A)
by
len(A) - 1
inside all instances of range function.

Related

Selection Sort in Python not sorting

I wrote a program for selection sort by first creating a function that finds the minimum element in the array. Then I iterate through the array placing the smallest element in the correct place in the array while replacing the smallest element.
This is my code :
a=[int(input()) for _ in range(6)]
def smallest_element(arr,x):
smallest = arr[x]
d = x
for j in range(x+1,len(arr)):
if arr[j] < smallest:
smallest = arr[j]
d = j
return d
for i in range(0,len(a)):
c = a[i]
if(c > a[smallest_element(a,i)]):
a[i] = a[smallest_element(a,i)]
a[smallest_element(a,i)] = c
print(a)
But the problem is my array is not getting sorted.
Input - [5,2,4,6,1,3]
Output - [5,2,4,6,1,3]
The error seems to be in your loop.
You assign the smallest value found to the current index.
a[i] = a[smallest_element(a,i)]
You then assign the value that was originally stored to the index where the smallest element is located.
a[smallest_element(a,i)] = c
You do however re-calculate the index of the smallest element, which always is the current index - because you just copied the smallest value to the current index.
first approach
I know of two solutions to this problem. First you may only search the index of the smallest element once per loop round. That way you do not re-calculate the index and write to the correct position.
for i in range(0, len(a)):
c = a[i]
indexOfSmallestElement = smallest_element(a, i)
smallestElement = a[indexOfSmallestElement]
if c > smallestElement:
a[i] = smallestElement
a[indexOfSmallestElement] = c
second approach
Another solution is to search the element starting from the current index + 1 instead of the current index, and thus skipping the entry that you've already changed.
Exchange a[smallest_element(a, i)] = c with a[smallest_element(a, i + 1)] = c.
I do however recommend to use the first approach as it recudes the amount of times the array is iterated over.
First, in your code, you have called the smallest_element(arr,x) 3 times which will consume more time for larger arrays. Instead we can store that value to a variable rather calling 3 times.
Secondly you are swapping 2 times one in function body and in if block.
So in the function body , find the current smallest element. Then return that index to main.Then if it is smaller than the present element (in the main for loop), then swap it.
#Find the smallest element
def smallest_element(arr,x):
small = x
for j in range(x+1,len(arr)):
if arr[j] < arr[small]:
small=j
return small
#now compare it with the current element
for i in range(0,len(a)):
c = a[i]
curr=smallest_element(a,i)
if(c > a[curr] and curr!=i):
a[i] = a[curr]
a[curr] = c
print(a)

How to apply multiprocessing in python3.x for the following nested loop

for i in range(1,row):
for j in range(1,col):
if i > j and i != j:
x = Aglo[0][i][0]
y = Aglo[j][0][0]
Aglo[j][i] = offset.myfun(x,y)
Aglo[i][j] = Aglo[j][i]
Aglo[][] is a 2D array, which consists of lists in the first row
offset.myfun() is a function defined elsewhere
This might be a trivial question but i couldn't understand how to use multiprocessing for these nested loops as x,y (used in myfun()) is different for each process(if multiprocessing is used)
Thank you
If I'm reading your code right, you are not overwriting any previously calculated values. If that's true, then you can use multiprocessing. If not, then you can't guarantee that the results from multiprocessing will be in the correct order.
To use something like multiprocessing.Pool, you would need to gather all valid (x, y) pairs to pass to offset.myfun(). Something like this might work (untested):
pairs = [(i, j, Aglo[0][i][0], Aglo[j][0][0]) for i in range(1, row) for j in range(1, col) if i > j and i != j]
# offset.myfun now needs to take a tuple instead of x, y
# it additionally needs to emit i and j in addition to the return value
# e.g. (i, j, result)
p = Pool(4)
results = p.map(offset.myfun, pairs)
# fill in Aglo with the results
for pair in pairs:
i, j, value = pair
Aglo[i][j] = value
Aglo[j][i] = value
You will need to pass in i and j to offset.myfun because otherwise there is no way to know which result goes where. offset.myfun should then return i and j along with the result so you can fill in Aglo appropriately. Hope this helps.

Convert list of integers to a single integer : ValueError

I am trying to convert a list of integers in Python into a single integer say for example [1,2,3,4] to 1234(integer). In my function, I am using following piece of code:
L = [1,2,3,4]
b = int(''.join(map(str, L)))
return b
The compiler throws a ValueError. Why so? How to rectify this issue?
You can do this like this also if that cause problems:
L = [1,2,3,4]
maxR = len(L) -1
res = 0
for n in L:
res += n * 10 ** maxR
maxR -= 1
print(res)
1234
another solution would be
L = [1,2,3,4]
digitsCounter = 1
def digits(num):
global digitsCounter
num *= digitsCounter
digitsCounter *= 10
return num
sum(map(digits, L[::-1]))
the digits() is a non pure function that takes a number and places it on place value depending on the iteration calling digits on each iteration
1. digits(4) = 4 1st iteration
2. digits(4) = 40 2nd iteration
3. digits(4) = 400 3rd iteration
when we sum up the array returned by map from the inverted list L[::-1] we get 1234 since every digit in the array is hoisted to it place value
if we choose not no invert L array to L[::-1] then we would need our digits function to do more to figure out the place value of each number in the list so we use this to take adv of language features

For loops python that have a range

So I'm writing a python code and I want to have a for loop that counts from the the 2nd item(at increment 1). The purpose of that is to compare if there are any elements in the list that match or are included in the first element.
Here's what I've got so far:
tempStr = list500[0]
for item in list500(1,len(list500)):
if(tempStr in item):
numWrong = numWrong - 1
amount540 = amount540 - 1
However the code doesn't work because the range option doesn't work for lists. Is there a way to use range for a list in a for loop?
You can get a subset of the list with the code below.
tempStr = list500[0]
for item in list500[1:]:
if(tempStr in item):
numWrong = numWrong - 1
amount540 = amount540 - 1
The [1:] tells Python to use all elements of the array except for the first element. This answer has more information on list slicing.
Use a function:
search_linear(mainValues, target)
This is the algorithm you are looking for: http://en.wikipedia.org/wiki/Linear_search
All you need to do is set the starting point equal to +1 in order to skip your first index, and than use array[0] to call your first index as the target value.
def search_linear(MainValues, Target):
result = []
for w in Target:
if (search_linear(MainValues, w) < 0):
result.append(w)
return result

Why am i getting a list index out of range error in my code?

The error occurs in line if data[l][0] == value:
def binary_pairs(data, value):
l = 0
h = len(data) - 1
while l < h and data[l]!= value:
m = (h + l) // 2
if data[m][0] == value:
l = m
elif data[m][0] < value:
l = m + 1
else:
h = m - 1
print("done")
if data[l][0] == value:
return l
else:
return -1
example input:
[ [ "dead", ["brian.txt","grail.txt"] ],
[ "eunt", ["brian.txt"] ],
[ "spank", ["grail.txt"] ]
]
I can see two potential issues with your code:
It seems odd that you use both data[l] and data[l][0] in comparisons.
If, for example, l==0 and h==1 and you end up taking the else (h = m - 1), you'd end up with h==-1, which is out of bounds. There could be other similar issues.
I can't run your code right now but here are a few ideas.
If you are trying to solve a problem, rather than trying to learn to write a binary search, consider using Python's bisect module.
http://docs.python.org/2/library/bisect.html
It is best practice in Python to comply with the coding standard called PEP 8; this recommends not using lower-case L as a variable name, or upper-case I.
http://www.python.org/dev/peps/pep-0008/
It would be cleaner to have the loop immediately return the index when it finds the value, rather than having the loop test at the top to make sure the value hasn't been found yet, causing the loop to end and then the value to be returned from the bottom of the function. If the loop ends, you can return -1 at the end of the function.
Your loop checks that the index is < h but does not check that the index is I >= 0. I suspect that this could be your problem.
When debugging a loop like this, it is often helpful to add print statements that log what is going on. You should print the value of the index, and print enough other lines to know whether it is being increased or decreased, and by how much.

Resources