Algorithm: IndexError: list index out of range (Python) - python

I'm new to python and I wanted to know why my program is displaying "IndexError: list index out of range" for line 4. Can anyone please help.
# A is the array and N is the size of the array.
A =[1,78,46,4,34,10,50,2]
N = len(A)
def Algorithm(A,N):
#B <- Array[N]
B = A[N]
B=[0]*N
for i in range(1,N):
B[A[i]]+=1
i=1
#for i <-- 1 to N
for j in range(1,N):
#for k <-- to B[j]
for k in range(0,B[j]):
A[i]=j
i+=1
return
Algorithm(A,N)
print(A)
Error:
2 N = len(A)
3 def Algorithm(A,N):
4 B = A[N]
5 B=[0]*N
6 for i in range(1,N):
IndexError: list index out of range

So the List index out of range comes from B = A[N] because N represents the total length of A.
However, elements of a list are indexed from 0 up to N-1, which gives you the length (N-1) - 0 + 1 => N. If you want to assign B to the last element of A, you can do that by B = A[N-1], or B = A[-1], since negative indices point to elements of the list from the end. However, given you redeclare B = [0] * N, you could do away with the first assignment

In Python, the first element of a list is addressed as zero rather than one. For example, to access the first element in a list called "numbers" you should write numbers[0] rather than numbers[1].
In B = A[N], you're trying to address the last element of list A by accessing A[N] (N corresponds to the length of list A). However, as previously explained, you have to minus one from this because the list starts at zero and not one. Therefore, the correct code would be B = A[N - 1].

A =[1,78,46,4,34,10,50,2]
N = len(A) # N = 8
def Algorithm(A,N):
B = A[N] # value of N is 8 and when you try to access A[8] its out of index range since the index is from 0 to 7
B=[0]*N
for i in range(1,N):
B[A[i]]+=1
i=1
#for i <-- 1 to N
for j in range(1,N):
#for k <-- to B[j]
for k in range(0,B[j]):
A[i]=j
i+=1
return
Algorithm(A,N)
print(A)
I would like to point out other things that i have noted in your code.
A =[1,78,46,4,34,10,50,2]
N = len(A)
def Algorithm(A,N):
B = A[N]
B=[0]*N # This line overwrites the above assignment.
for i in range(1,N):
B[A[i]]+=1 # B[A[i]] -- so i guess during execution the A[i] will be a value from list A . hence B[A[i]] might become B[78] , B[46] etc (sorry if i have misunderstood)
i=1
#for i <-- 1 to N
for j in range(1,N):
#for k <-- to B[j]
for k in range(0,B[j]):
A[i]=j
i+=1
return
Algorithm(A,N)
print(A)

Related

Replace Adjacent Elements of Circular Array to Make All Elements Equal

You are given a circular array A containing N integers. You can perform the
following operation on this array any number of items:
• For each i, replace A[i] by A[i-1], A[i] or A[i+1] i.e. you can keep the
current element or replace it by an adjacent element . Note that due to
circularity of the array adjacent elements exist even for the first and
the last element. In particular, A[i-1] for i=0 is the last element.
Determine the minimum number of steps needed to make all the elements of
the array equal.
Input Format
The first line contains an integer, N, denoting the number of elements in A.
Each line i of the N subsequent lines (where 0 $i< N) contains an integer
describing A[i].
Constraints
1 <= N <= 10^3
Sample input: 4 2 2 1 1 => Sample output: 1
Sample input:3 1 1 1 => Sample output: 0
Sample input:4 1 2 3 4 => Sample output: 2
I build the following code, it passes all visible test cases on platform, but not passing invisible test cases(that i'm not sure, what are they).Please help me to find any edge cases, if i forgot something here.
from collections import Counter
def make_equal(A):
count = 0
idx = []
map = Counter(A)
value = sorted(map.values(), reverse=True)[0]
for k, v in map.items():
if v == value:
key = k
for i, val in enumerate(A):
if val == key:
idx.append(i)
new_set = set(idx)
while len(new_set) < len(A):
for j in idx[:]:
l = (j + 1) % len(A)
m = (j - 1) % len(A)
idx.append(m)
idx.append(j)
idx.append(l)
count += 1
new_set = set(idx)
return count
print(make_equal(A))

Problem while trying to implement iterative solution to fibonacci series using lists

def fibo(m):
dp = []
for i in range(m+1):
dp.append(0)
dp[0] = 1
dp[1] = 1
if(m>1):
for i in range(2,m+1):
dp[i] = dp[i-1] + dp[i -1]
return dp[m]
I am getting an error that says that the list index is out of bound can any resolve it and can post the correct code . Thanks.
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-92-ea67e751dd0e> in <module>()
12 return dp[m]
13
---> 14 fibo(0)
<ipython-input-92-ea67e751dd0e> in fibo(m)
6 dp.append(0)
7 dp[0] = 1
----> 8 dp[1] = 1
9 if(m>1):
10 for i in range(2,m+1):
IndexError: list assignment index out of range
When m == 0, the initial for loop only appends dp[0], so assigning to dp[1] gets an error.
Instead of assigning after the loop, append 1 in the loop. The elements after dp[1] will then be overwritten by the second loop, so it doesn't matter what their original values are.
def fibo(m):
dp = []
for i in range(m+1):
dp.append(1)
if(m>1):
for i in range(2,m+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[m]
Another way to do it is to initialize dp with the first two elements, and then append to it in the loop that calculates each element of the series.
def fibo(m):
dp = [1, 1]
if(m>1):
for i in range(2,m+1):
dp.append(dp[i-1] + dp[i-2])
return dp[m]
Why adding zeros to your list before assigning values ? When you pass m = 0, you will have an error when trying to access dp[1].
Also, there is a typo in dp[i] = dp[i-1] + dp[i -1]. Fibonacci is the sum of the (n-1)th and (n-2)th elements like this dp[i] = dp[i-1] + dp[i -2]
I would do something like :
def fibo(m):
dp = []
dp.append(0)
dp.append(1)
if(m>1):
for i in range(2,m+1):
dp.append(dp[i-1] + dp[i -2])
return dp[m]
You can also initialize the dp list in the beginning to the length of the number and then just store the answer in the respective index.
def fib(n):
if n<=1:
return n
dp=[0]*(n+1)
dp[1]=1
for i in range(2,n+1):
dp[i]=dp[i-2]+dp[i-1]
return dp[n]
>>> print(fib(5))
5
>>> print(fib(9))
34
The IndexError you are seeing occurs when you pass in m as 0. In this case the list contains just a single element( dp = [0] ), but your code tries to access the second element by index:
i.e. dp[1] = 1 (hence the index error)
An easy way to get around this is to not initialize the list at all, and directly start appending your fibonacci series numbers to it.
def fibo(m):
dp = []
dp.append(1)
dp.append(1)
# Use a loop for the remainder of the numbers. Will only execute if m > 1
for i in range(2,m+1):
dp.append(dp[i-1] + dp[i-2])
return dp[m]
An alternative solution would be to not use a list at all (since you are only interested in the nth element of the series). The solution is quite concise:
def fibo(m):
a, b = 1, 1
while (m > 0):
a, b = b, a+b # At every iteration, "a" takes the value of the next element in the fibo series.
m -= 1
return a

What happens when we a negative value in python's for loop?

x = 10
l = [1]
for i in range(x):
# Modified v
print("Row", i + 1, l)
newlist = []
newlist.append(l[0])
for i in range(len(l) - 1):
newlist.append(l[i] + l[i+1])
newlist.append(l[-1])
l = newlist
I dont understand what happens when the index goes negative
When you give negative index, value at that index is returned. For list
a=[1,2,3]
we can say
value 1 is at index 0
value 2 is at index 1
value 3 is at index 2
or
value 3 is at index -1
value 2 is at index -2
value 1 is at index -3
If you go outside this range of indexes which is in this case negative 3 to positive three, you will get
IndexError: list index out of range
For your code, second for block is never executed and hence you are not seeing index error.
x = 10
l = [1]
for i in range(x):
print("Row", i + 1, l)
newlist = []
newlist.append(l[0])
# Length l is 0,so below code inside for is never executed as range is empty
for i in range(len(l) - 1):
newlist.append(l[i] + l[i+1])
newlist.append(l[-1])
l = newlist

Longest arithmetic progression with a hole

The longest arithmetic progression subsequence problem is as follows. Given an array of integers A, devise an algorithm to find the longest arithmetic progression in it. In other words find a sequence i1 < i2 < … < ik, such that A[i1], A[i2], …, A[ik] form an arithmetic progression, and k is maximal. The following code solves the problem in O(n^2) time and space. (Modified from http://www.geeksforgeeks.org/length-of-the-longest-arithmatic-progression-in-a-sorted-array/ . )
#!/usr/bin/env python
import sys
def arithmetic(arr):
n = len(arr)
if (n<=2):
return n
llap = 2
L = [[0]*n for i in xrange(n)]
for i in xrange(n):
L[i][n-1] = 2
for j in xrange(n-2,0,-1):
i = j-1
k = j+1
while (i >=0 and k <= n-1):
if (arr[i] + arr[k] < 2*arr[j]):
k = k + 1
elif (arr[i] + arr[k] > 2*arr[j]):
L[i][j] = 2
i -= 1
else:
L[i][j] = L[j][k] + 1
llap = max(llap, L[i][j])
i = i - 1
k = j + 1
while (i >=0):
L[i][j] = 2
i -= 1
return llap
arr = [1,4,5,7,8,10]
print arithmetic(arr)
This outputs 4.
However I would like to be able to find arithmetic progressions where up to one value is missing. So if arr = [1,4,5,8,10,13] I would like it to report that there is a progression of length 5 with one value missing.
Can this be done efficiently?
Adapted from my answer to Longest equally-spaced subsequence. n is the length of A, and d is the range, i.e. the largest item minus the smallest item.
A = [1, 4, 5, 8, 10, 13] # in sorted order
Aset = set(A)
for d in range(1, 13):
already_seen = set()
for a in A:
if a not in already_seen:
b = a
count = 1
while b + d in Aset:
b += d
count += 1
already_seen.add(b)
# if there is a hole to jump over:
if b + 2 * d in Aset:
b += 2 * d
count += 1
while b + d in Aset:
b += d
count += 1
# don't record in already_seen here
print "found %d items in %d .. %d" % (count, a, b)
# collect here the largest 'count'
I believe that this solution is still O(n*d), simply with larger constants than looking without a hole, despite the two "while" loops inside the two nested "for" loops. Indeed, fix a value of d: then we are in the "a" loop that runs n times; but each of the inner two while loops run at most n times in total over all values of a, giving a complexity O(n+n+n) = O(n) again.
Like the original, this solution is adaptable to the case where you're not interested in the absolute best answer but only in subsequences with a relatively small step d: e.g. n might be 1'000'000, but you're only interested in subsequences of step at most 1'000. Then you can make the outer loop stop at 1'000.

How is this list index out of range? (Fibonacci numbers exercice)

This code should print the sum of the even numbers in the first ten numbers of the Fibonacci sequence.
#Creates a list with the first ten Fibonacci numbers.
l = [1,2]
for i in range(10):
l.append(l[i]+l[i+1])
for i in l:
#If an element of the Fibonacci list is uneven, replace it with zero.
if l[i]%2 != 0:
l[i] = 0
#Print the sum of the list with all even Fibonacci numbers.
print sum(l)
When I execute this I get:
File "pe2m.py", line 6, in <module>
if l[i]%2 != 0:
IndexError: list index out of range
I don't get how its going out of range, could someone clarify?
Your problem is for i in l: it doesn't give you the indices, it gives you the list elements. As the elements are integers, they could be valid (and the first few will be) but they don't have the values you want -- you'll have to iterate over a range again.
You are looping over the values not the index positions!
Use the following code instead:
#Creates a list with the first ten Fibonacci numbers.
l = [1,2]
for i in range(10):
l.append(l[i]+l[i+1])
for i in range(len(l)):
#If an element of the Fibonacci list is uneven, replace it with zero.
if l[i]%2 != 0:
l[i] = 0
#Print the sum of the list with all even Fibonacci numbers.
print sum(l)
You cannot index a list with the value from the list as it is not guaranteed that the value will be within the list boundary
Seeing your code, I feel you are planning to do something as below
>>> for i,e in enumerate(l):
#If an element of the Fibonacci list is uneven, replace it with zero.
if e%2 != 0:
l[i] = 0
Interestingly you can do the same as below. (Edited after seeing glglgl's comment]
>>> print sum(e for e in l if e%2)
Python's for x in y construct returns the values/elements of a sequence in x, not their index.
As for the Fibonacci numbers: The sequence starts with 1, 1 and not 1, 2. And the sum can be done simpler like this:
a, b = 1, 1
s = 0
for i in range(10):
a, b = b, a+b
if b % 2 = 0:
s += b
print s
If you need to get the sum of the first N even numbers, you would do:
a, b = 1, 1
s = 0
count = 0
while count < 10:
a, b = b, a+b
if b % 2 = 0:
s += b
count += 1
print s
And just for fun the version with generators in a functional style:
from itertools import islice
def fib():
a, b = 1, 1
yield a
yield b
while True:
a, b = b, a+b
yield b
even_sum = reduce(lambda x, y: x+y if y % 2 == 0 else x, islice(fib(), 10), 0)

Categories