Python Force List Index out of Range Exception - python

I have a list of lists
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
I want the code to throw an Array Out of Bounds Exception similar to how is does in Java when the index is out of range. For example,
x[0][0] # 1
x[0][1] # 2
x[0-1][0-1] # <--- this returns 9 but I want it to throw an exception
x[0-1][1] # <--- this returns 7 but again I want it to throw an exception
x[0][2] # this throws an index out of range exception, as it should
If an exception is thrown, I want it to return 0.
try:
x[0-1][0-1] # I want this to throw an exception
except:
print 0 # prints the integer 0
I think basically anytime the index is negative, throw an exception.

You can create your own list class, inheriting the default one, and implementing the __getitem__ method that returns the element in a specified index:
class MyList(list):
def __getitem__(self, index):
if index < 0:
raise IndexError("list index out of range")
return super(MyList, self).__getitem__(index)
Example:
>>> l = MyList([1, 2, 3])
>>> l[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __getitem__
IndexError: list index out of range
>>> l[0]
1
>>> l[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getitem__
IndexError: list index out of range

There is a better way to handle the border cases: just increase the array by two in both dimensions and fill all border with a default (e.g. 0) and never update them. For neighbourhood and update, just search the inner field (index 1..(len-2)), instead of 0..len-1. So, the indexes will never be out of bounds for the neighbourhood search. This elliminates the need for special treatment.
(I did this many years ago for the same usage, but in a different language - Pascal, iirc.)

try:
x[len(x)][0]
except IndexError:
...
This will eventually raise an index error, as len(any_list) is always +1 past the last valid index.
Btw. it is good advise only to catch expected exceptions (the ones you actually want to handle); your code will catch any exception.
Ok, just read your comment. Your original question sounded as if you wanted to provoke an index error.

Related

list index out of range in my coding

Can anyone help me fix this error I keep getting please. I have tried to look for a solution but I can't find any. Below is the error message and also part of my coding
Please enter your class Y or X or Z: Y
Traceback (most recent call last):
File "/Volumes/LIAM'S USB/DEV6 FINAL.py", line 118, in <module>
score=int(items[1])
IndexError: list index out of range
results={
start=True
while (start):
pupil_class=input("\nPlease enter your class Y or X or Z: ")
if pupil_class == ("Y"):
classfile="Class_Y_results.txt"
elif pupil_class == ("X"):
classfile="Class_X_results.txt"
elif pupil_class == ("Z"):
classfile="Class_Z_results.txt"
f=open(classfile,'r')
for line in f:
items=line.split(',')
name=items[0]
score=int(items[1])
if name in results:
results[name].append(score)
else:
results[name]=[]
results[name].append(score)
f.close()
A certain line in your Class_Y_Results.txt only has one entry (not separated by commas), hence the list returned by items=line.split(',') only has a length of 1 (or maybe 0), causing score=int(items[1]) to throw an IndexError.
Sample:
>>> a = "foo,bar"
>>> b = "foo"
>>> len(a.split(','))
2
>>> len(b.split(','))
1
>>> a.split(',')[1]
'bar'
>>> b.split(',')[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
There is probably an empty like in one of your files. This will not contain a comma, so you will not have an item[1], and this produces the error message you see.
Check how many fields you get back from the split to solve this.

Merge sort in Python - `int` object is not iterable

Here is merge sort implementation in Python. I am getting the error int object is not iterable when merge_arrays() function is called. Any suggestions will be highly appreciated.
arr = [1,5,4,7,6,8,3,2,9]
def merge_arrays(_arr_left, _arr_right):
sorted_arr = []
left, right = 0, 0
for i in range(0, len(arr)):
if (_arr_left[left] < _arr_right[right]):
sorted_arr.extend(_arr_left[left])
left += 1
else:
print _arr_right[right], right
sorted_arr.extend(_arr_right[right])
right += 1
return sorted_arr
def merge_sort(_arr):
if (len(_arr) <= 1):
return _arr
_arr_left = merge_sort(_arr[:len(_arr)/2])
_arr_right = merge_sort(_arr[(len(_arr)/2):])
return merge_arrays(_arr_left, _arr_right)
try:
merge = merge_sort(arr)
print merge
except Exception as e:
print e
That particular error is coming from the fact that you're saying sorted_array.extend(_arr_left[left]). You're asking for sorted_array to have appended to it every element of the "iterable" _arr_left[left]. But _arr_left[left] isn't really iterable, it's just whatever int is at index left in _arr_left.
If you don't try then except and print the Exception, you'll see a full stack trace that will tell you which line is bad.
File "merge.py", line 27, in <module>
merge = merge_sort(arr)
File "merge.py", line 22, in merge_sort
_arr_left = merge_sort(_arr[:len(_arr)/2])
File "merge.py", line 22, in merge_sort
_arr_left = merge_sort(_arr[:len(_arr)/2])
File "merge.py", line 25, in merge_sort
return merge_arrays(_arr_left, _arr_right)
File "merge.py", line 9, in merge_arrays
sorted_arr.extend(_arr_left[left])
TypeError: 'int' object is not iterable
So you can see the problem starts at line 9. You can also insert import pdb; pdb.set_trace() before you think the Exception comes up to run the python debugger and step through your program's progression to see where the Exception appears.
As other answers have mentioned, you need to change extent to append. However, as you said in comments, you are getting list index out of range error because you are iterating over the size of arr which is 9 but subarrays have much lesser length. Try changing your merging two arrays code to the following.
while (len(_arr_left) > left) or (len(_arr_right) > right):
if (len(_arr_left) > left) and (len(_arr_right) > right):
if (_arr_left[left] < _arr_right[right]):
sorted_arr.append(_arr_left[left])
left += 1
else:
sorted_arr.append(_arr_right[right])
right += 1
elif (len(_arr_left) > left):
sorted_arr.append(_arr_left[left])
left += 1
else:
sorted_arr.append(_arr_right[right])
right += 1
As you can see in the above code, we have to test for various conditions. If both subarrays contains elements, then we compare them to each other and append to sorted_arr depending on the value evaluation. If not then we append values from individual sub-arrays. It would have been easier if instead of using left and right, you were using pop so you wouldn;t have to keep tracking of left and right
Finally, here is the working version of your code. You also need to modify
return merge_sort(...) to sorted_arr = merge_sort(...) return sorted_arr so it doesn't print everytime it returns sorted_arr
In your line 9:
sorted_arr.extend(_arr_left[left])
sorted_arr is a list
_arr_left is a list
left is an int
So, the problem is:
>>> a = [1,2,3,4]
>>> a.extend(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>>
Solution:
You can use list.append() instead of extend().
>>> a = [1,2,3,4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>>
PS: You might have other issues with your code.

ValueError in range function (to print 3^(2^n)) in python

while trying to print the sequence of power(3,2^n), i.e, 3^2,3^4,3^8 , I tried using the following line using range function.Is it possible to use the range function to get the desired output? If so please let me know where did I went wrong.
for i in range(3,1000, i*(i-1)): print (i*i)
for example, the following output is expected for i=3,9,81
i*i:=9,81,6561
But the error is :
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
for i in range(3,1000, i*(i-1)): print (i*i)
ValueError: range() arg 3 must not be zero
How can the step value be zero in this case?
You could use a list comprehension to build a list of all of your powers:
mylist = [3**(2**n) for n in range(1,10)] # or whatever range
and then iterate through the comprehension to print all of your results if you want. You can do other stuff with your results in this loop instead of print them.
for item in mylist:
print(item) # print each item on a new line
i = 2
while 3**i < 1000:
print(3**i)
i *= 2
I'm pretty sure what you want to do is very similar to this question. You want to be calling a list comprehension:
powersofthree = [3**(2**i) for i in range(10)]
which returns
[3, 9, 81, ... ]
Then you can print the result at you leisure.
Also, as many in the comments have pointed out, you used i before it was defined, which is why you encountered an error

How to add elements of a list in Python 3.5.5?

My assignment is:
Write a function sumOfPairs that has one parameter of type list. The
list can be empty or contain integers. The length of the list must be
0 or an even number. If the length of the list is not 0 and is not
even, the function should print an error message and return None. You
can assume the list contains only integers. The function returns the
list of the sum of each consecutive pair of the numbers in the list.
Example: If the list is [1,5,2,10,15,2,9,3], the function returns
[6,12,17,12].
My attempt so far is:
def sumOfPairs (list1: list):
if len(list1) != 0 and len(list1)%2 != 0:
print ("Error")
return (None)
else:
x = list1.index(int)
answer = []
while x<=len(list1):
newListValue=list1(x)+list1(x+1)
answer.insert(x,newListValue)
x=x+2
return (answer)
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
Yet it yields the following error upon execution:
Traceback (most recent call last):
File "C:\Users\Andrew\Desktop\lab3.py", line 79, in <module>
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
File "C:\Users\Andrew\Desktop\lab3.py", line 71, in sumOfPairs
x = list1.index(int)
ValueError: <class 'int'> is not in list
How can I fix this?
def sum_of_pairs(l):
if len(l) % 2: # if the length of the list mod 2 has a remainder, the list length is uneven
print("Error, uneven length list")
else: # else, step through the list in pairs and add each pairing
return [l[i]+ l[i+1] for i in range(0,len(l),2)]
In [3]: (sum_of_pairs([1,5,2,10,15,2,9,3]))
Out[3]: [6, 12, 17, 12]
A python function that does not specify a return value as in the if len(l) % 2: will return None by default so we do not need to explicitly return None.
In [11]: l = [1,5,2,10,15,2,9,3]
In [12]: [sum(pair) for pair in zip(l[0::2],l[1::2])]
Out[12]: [6, 12, 17, 12]
I don't particularly like your approach here, but let's take a look at the error specifically.
Traceback (most recent call last):
File "C:\Users\Andrew\Desktop\lab3.py", line 79, in <module>
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
File "C:\Users\Andrew\Desktop\lab3.py", line 71, in sumOfPairs
x = list1.index(int)
ValueError: <class 'int'> is not in list
Now look at the line it occurs on, and try to say it in English
x equals the first index in list1 where the value is 'int'
Note that it's not the value is AN int! This is crucial, and is the reason for the error. Your list does not INCLUDE the class int. That would be something like:
[1,2,3,int,5,6,7,8] # not your list
Much easier would be to test that ALL your indices contain ints, then just iterate through the list. Let's try that (even though your exercise says otherwise, partially to keep you from just copy/pasting this!! :D)
def sum_of_pairs(lst: list):
if len(lst) == 0 or len(lst) % 2 != 0:
raise ValueError("Invalid list length")
# makes more sense to raise an exception here than print an error
if any(not isinstance(int, el) for el in lst):
# if any element is not an int:
raise ValueError("Invalid list contents")
result_list = []
for element in lst:
first_el = element
second_el = next(lst)
# advance the iterator once to grab the next element
result_list.append(first_el + second_el) # add them and append
return result_list
Or even easier if you know how to use the grouper recipe, which is in the pydocs for the itertools module here:
def grouper(iterable, n):
return zip(*iter([iterable])*n)
def sum_of_pairs(lst: list):
# validate here, I'm not going to re-write it
return [sum(pair) for pair in grouper(lst, 2)]

Python error with a bubble sort function

For this function for some reason I get errors, and I can't figure out what's wrong with it.
def bubbleSort(lis):
for pas in lis:
for i in pas:
if lis[i] > lis[i+1]:
lis[i],lis[i+1] = lis[i+1],lis[i]
I get the following errors:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
bubbleSort(hello)
File "C:/Users/albert/Desktop/test.py", line 4, in bubbleSort
for i in pas:
TypeError: 'int' object is not iterable
Assuming lis is a list of integers, pas will be a single integer. for i in pas: fails because there are no is in a single integer.
Bubble sort is typically done with an outer loop that goes while there are any changes, and an inner loop that iterates over n-1 indices, not list elements. You can find a standard implementation in many places, here's the rosetta code one:
def bubble_sort(seq):
"""Inefficiently sort the mutable sequence (list) in place.
seq MUST BE A MUTABLE SEQUENCE.
As with list.sort() and random.shuffle this does NOT return
"""
changed = True
while changed:
changed = False
for i in xrange(len(seq) - 1):
if seq[i] > seq[i+1]:
seq[i], seq[i+1] = seq[i+1], seq[i]
changed = True
return None

Categories