Q: list assignment index out of range - python

>>> def lcm(a,b):
if a<<b:
c=a
a=b
b=c
c=0
lit=[a,b,c]
n=3
while (not lit[n%3]%lit[(n%3)+1]==0):
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
if lit[(n%3)+2]==0:
d=lit[(n%3)+2]
print d
else:
n=n+1
This is the code, trying to build a function lcm that finds the least common multiplier of a and b. Not really the cleanest code of the bunch, but sadly this was all I could do. It would really be nice if this lump of code could be a little lighter.
So, err, back to the point, I called for lcm, and it just blurts out error messages.
This is what it says:
>>> lcm(78696,19332)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
lcm(78696,19332)
File "<pyshell#1>", line 10, in lcm
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
IndexError: list assignment index out of range
Aaaaand I have got absolutely no idea what I am supposed to do now.
What can I do now?

Python lists are zero-indexed.
So lit[0] = a, lit[1] = b, and lit[2] = c.
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
If n = 1, then (n%3)+2 equals 3. If n = 2, then (n%3)+2 equals 4.
If you want to guarantee that you're accessing your list at a valid index, then you want to % by the length of the list- which you're doing, just not at the right place.
Without looking too deeply into your code, I think it's just another lesson that order of operations matters. Try (n+2)%3 instead of (n%3)+2.
x%3 will always be within the range [0, 2]- so that's why you want to mod at the very end. (x%3+n ends up in the range [n, 2+n].)

n%3 can be as big as 2. so n%3 + 1 could be as much as 3. The list lit has only 3 items, so at this line,
lit[(n%3)+2]=lit[n%3]%lit[(n%3)+1]
if n%3 == 2, then accessing lit[(n%3)+1] will lead to index out of range error.

Related

List index out of range Error in python ,but index is in range how is it?

def longestValidParentheses(si):
cnt=0
s=[]
for _ in range(0,len(si)):
s.append(si[_])
print(s[6])
for i in range(0,len(s)-1):
print(i)
if (s[i]=="("):
for j in range(0,len(s)):
if (s[j]==")"):
cnt+=2
s.pop(j)
break
print(cnt)
return cnt
longestValidParentheses(")(())()")
This my code to find how many correctly formed parenthesis
but in the second loop I AM getting an error like this
Traceback (most recent call last): File "F:/yy.py", line 17, in
longestValidParentheses(")(())()") File "F:/yy.py", line 9, in longestValidParentheses
if (s[i]=="("): IndexError: list index out of range
but list is not out of range
You have a dynamic variable (len(s)) used as your upper bound on your range. A quick check is to throw a print statement of len(s) after you pop. The first pop occurs early enough that your original loop is still valid, but the second time you pop you have len(s) = 5, and then you try to access s[5] as i is incremented to 5. This is out of bounds since the two pops have reduced your string to 0, 1, 2, 3, 4 at this point.
You have two options here, you can remove the pop so that the indices do not change in the loops, or you can modify the logic (my first thought would be a while loop that increments or pops not both).
Edit: I realize JoshuaF commented the fix just before I did.

Python - TypeError: 'NoneType' object is not iterable Exit Code at CodeWars - Are they the same?

So I'm doing a challenge from CodeWars that says:
"Given two arrays a and b write a function comp(a, b) that checks whether the two arrays have the "same" elements, with the same multiplicities. "Same" means, here, that the elements in b are the elements in a squared, regardless of the order."
My code for it is:
def comp(array1, array2):
if array1==None or array2==None:
return False
array1 = list(array1)
array2 = list(array2)
array1.sort()
array2.sort()
z= 0
for i in range(len(array1)):
if array1[i]**2 == array2[i]:
z+=1
if z == len(array1):
return True
else:
return False
Now, I know there must be much easier code for this task, but I'm still a beginner programmer.
So all the tests are passed positively.
But I keep getting an exit code:
Traceback (most recent call last):
File "main.py", line 21, in <module>
test.assert_equals(comp(a1, a2), False)
File "/home/codewarrior/solution.py", line 10, in comp
if array1[i]**2 == array2[i]:
IndexError: list index out of range
If I remove the first "if array1= None.... return False" statement, it gives this exit code instead:
Traceback (most recent call last):
File "main.py", line 18, in <module>
test.assert_equals(comp(a1, a2), False)
File "/home/codewarrior/solution.py", line 3, in comp
array2 = list(array2)
TypeError: 'NoneType' object is not iterable
So no matter what, my code has something wrong in it, haha. Any solution to this?
The error you can cam be dueto different lenghts of lists -you do not guard against that.
comp([1,2,3], [1,2])
You can simplify your code using enumerate() on one array and then look into the other one. I highly doubt your arrays need to be cast into a list - they probably already are - and even if, you could do that in one step using sorted():
def comp(array1, array2):
if array1 is None or array2 is None: # compare to None with is
return False
if len(array1) != len(array2):
return False
array1 = sorted(array1)
array2 = sorted(array2)
for idx,num in enumerate(array1):
if num*num != array2[idx]:
return False # early return on first mismatch
return True
You still might get better results if you optimize more - but you can do that on your own time :o) - f.e. think about a check for this:
comp( [2]*100000000,[4]*100000000)
You can easily speed that up if you use a sorted list of a set() of your inputs instead of sorted list and that way you can eliminate about 99999999 checks which will make a dent into your runtime (unless your dataset only contains unique values to begin with). And if you got set()'s .. they are really fast in looking up if something is in them - far better and faster then sorting huge lists to begin with ...

Variation of suffix array in python

I'm relatively new to computer science, and I'm learning how to code in python. I'm trying to figure out how to make a function that takes a list and returns a list of suffixes from the inputted list, in order from shortest length to longest length. For example, entering
[3,4,2,-9,7,6,1]
to the function would return
[[],[1],[6,1],[7,6,1],[-9,7,6,1],[2,-9,7,6,1],[4,2,-9,7,6,1],[3,4,2,-9,7,6,1]]
I've tried several approaches, but so far I'm not having much luck. Here is what I have so far:
def h(m):
newlist = []
x = 0
y = (len[m])-1
while x in range(y):
sublist = []
sublist = sublist + m[x:y]
newlist.append(sublist)
x += 1
return new list
When I try to run the function by entering something like
a = [3,4,2,-9,7,6,1]
h(a)
I get an error:
Traceback (most recent call last):
File "<pyshell#239>", line 1, in <module>
h(a)
File "<pyshell#238>", line 4, in h
y = (len[m])-1
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
My objective with this bit of code was simply to create a the list of suffixes without sorting them by length. After I figure out how to create this new list I will add the sorting bit of the code. Keep in mind this is not a homework assignment. Any help would be greatly appreciated!
Possible solution is using list comprehension:
[l[i:] for i in range(len(l), -1, -1)]
This code uses slicing and list comprehension to simply return a list of slices from the end. Using your code, small modification is required - len is a function and not a dictionary, therefore you need to use the call operator () instead of subscript operator [].
y = len(m) - 1
That will not yield correct result though, because you will not get the last suffix and empty suffix. In order to cover these two, you will need to modify y or the loop to cover them
y = len(m) + 1
or better
while x in range(y + 1):
use parenthesis to get the length of the list:
y = len(m) - 1
Your error is in your len:
(len[m]) - 1
len is a function, and you can't index or slice or the what not. Do this instead:
y = len(m) - 1
There's also one other error:
return new list
Should be: (You can't have spaces in variables)
return newlist

Error in below python code

I am new to python program. the below code has some error with list.
len = []
def collatz_length(n,count):
++count
if len[n]:
return len[n]
if n == 1:
len[n] = count
elif n & 1:
len[n] = count + collatz_length(3 * n + 1,0)
else:
len[n] = count + collatz_length(n >> 1,0)
return len[n]
print collatz_length(13,0)
i am trying to figure out the length.But the gives error
OUTPUT
Traceback (most recent call last):
File "collatz.py", line 21, in <module>
print collatz_length(13,0)
File "collatz.py", line 9, in collatz_length
if len[n]:
IndexError: list index out of range
It means that n is beyond the length of the list (which is initially zero). Rather than doing len[n], you want to see if n is in your list:
# Renaming your array to my_array so that it doesn't shadow the len() function,
# It's also better to put it as a parameter, not a global
def collatz_length(n, count, my_array):
if n < len(my_array):
return my_array[n]
# ... all your elses
If you have an array with 5 things in it, and try to access array[5], you are reading outside the bounds of the array. I think that is what is happening, but your code is also very hard to understand. If that's not what is happening, you may need to add some comments or otherwise clarify what you are doing. It looks like you have an empty array and are trying to access location 13 in it, which makes no sense.

Lists in Python (how to add the elements)

I just started with Python. Had Haskell before. In Haskell, I worked most of the time with/on lists. In Python I want do so.
I have a list of:
l = [1,2,3,4]
How can I add the 4 elements in the list, so that I get 10 as result (1+2+3+4)
I need a recursive function and an iterative (not clean and stable as iterative , but nevertheless).
In Haskell I did this:
sum [] = 0
sumlist(x:xs) = x + sumlist xs
In Python I tried this:
def sumlist(l)
if l == 0: #or Nil, i do not know
result 0
else:
l [0] + sumlist(l)
but that does not work, maybe I am still to focused on Haskell's implementation style.
Would be great if I get some help.
Edit:
If you do not wish to use sum, you can make your own function1:
>>> def sumlist(seq, start=0):
... return sumlist(seq[1:], start + seq[0]) if seq else start
...
>>> lst = [1, 2, 3, 4]
>>> sumlist(lst)
10
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> sumlist(lst)
45
>>> sumlist(lst, 10) # You can specify a number to start at too
55
>>>
1Note: It is assumed that you will pass in a sequence of numbers.
Just use the sum built-in:
>>> l = [1, 2, 3, 4]
>>> sum(l)
10
>>>
From the docs:
sum(iterable[, start])
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterable's items are
normally numbers, and the start value is not allowed to be a string.
I haven't used Haskell, but in Python objects are rich in that they know how to work with other objects. You can think of it like the "interface between objects" is well understood, and everyone is expected to behave nicely:
EAFP
Easier to ask for forgiveness than permission. This common Python
coding style assumes the existence of valid keys or attributes and
catches exceptions if the assumption proves false. This clean and fast
style is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common to many
other languages such as C.
So the idea is if there a function in the standard library called sum, you can be sure it does at least two things:
Knows how to sum up things it can sum up.
If it doesn't know how to sum it up, it will raise an Exception.
Once you understand how this works, you can start passing anything to sum to see what it does:
>>> sum((1,2,3)) # a list
6
>>> sum([1,2,3]) # a tuple
6
>>> sum((1,)) # a tuple with one object
1
>>> sum([2]) # a list with one object
2
So as long as the item is iterable, sum can do its thing. Of course, when you pass it something it cannot work with, you get the appropriate exception:
>>> sum(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> sum('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Note that a string is iterable in Python, which is why you get a different exception.
After you comment here:
Is there another way summing them up , or is it just this one ?
Its worth pointing out the zen of python which is kind of a guide on what makes code "pythonic", which states:
There should be one-- and preferably only one --obvious way to do it.
So the obvious way to sum things up would be with a function named sum.
Your code isn't actually too far off. empty lists are "falsy", so you can do something like:
def sumlist(lst):
if not lst:
return 0
else:
# Add the first element to the sum of the remaining elements.
return lst[0] + sumlist(lst[1:])
Of course, I'm assuming that you're doing this as part of a homework assignment where you're learning about recursion -- This would be horrible in any sort of production code where you should really just use sum (the builtin function).
If you are looking for a method other than the obvious sum you can use reduce:
>>> l = [1,2,3,4]
>>> import operator
>>> reduce(operator.add, l)
10
If you want another function, you could do:
def sum_l(l):
rtr=0
while l:
rtr+=l.pop()
return rtr
That function is destructive to the list. If you want to keep the list, call it with a copy of the list:
n=sum_l(l[:])
Yet another (that does not destroy the list) is to use a for loop on the iterable:
def sum_l(l):
rtr=0
for e in l:
rtr+=e
return rtr
Here are two ways you can compute the sum:
Just use the in-built sum function:
sum(l)
Using a for loop:
sum_val = 0
for i in range(0, len(l)):
sum_val += l[i]
Using recursion to compute a sum is just waste of computing resources. Do not use recursion until its absolutely necessary.

Categories

Resources