Unable to Solve 'list index out of range' error - python

I am trying to create a function that counts the number of prime numbers for a given range and I receive a list index out of range error on the commented line below and cannot figure out what is wrong.
def count_primes(num):
my_list = list(range(2,num+1))
for i in my_list:
x = my_list[i] # This line
y = not x
r = x%y if y != 0 else 0
z = []
if x%1 == 0 and x%x == 0 and r != 0:
z.append(x)
return len(z)

When you iterate over the list with for i in list, i variable contains items of the list and not its indexes.
Your list contains numbers [2, 3, 4,.. num]. And the max index in it is num-2. So when you try to refer to list[num-1] or list[num] you get this error.
The solution is to remove the line in bold and use x instead of i in for loop statement: for x in list.

Related

finding index[] of odd values in a list of integers?

I am trying to find the index value of some odd integers in a list. The program at its current stage only returns a new list containing only the odd integers.
image of my code
This program returns the values [3, 5, 7]. How would i be able to retrieve the index of these odd values instead? For example, [0, 1, 3, 5] for the list shown above.
I have tried "position = dataItem1.index()". I understand that i would need to input an index value within the index brackets.
you can use also use enumerate : it returns the index of the element and the element (also, in python you can loop directly over the elements of a list, no need of while loops). I also encourage the use of .append() to add an element to a list, this is clearly more efficient than concatenate two lists as you do:
l = [0, 3, 2, 3, 4, 7, 6]
def get_odds_index(l):
res = []
for idx, val in enumerate(l):
if val % 2 != 0:
res.append(idx)
return res
get_odds_index(l)
Instead of adding the element on that index in the odd list, just add index
Like this
def positionOfOdds(arr):
odds = []
length = len(arr)
index = 0
while index < length:
data = arr[index]
if data % 2 != 0:
odds.append(index)
index += 1
return odds
you already know the index, it is the loop variable
def positionOfOdds(arr):
odds = []
length = len(arr)
index = 0
while index < length:
data = arr[index]
if data % 2 != 0:
odds = odds + [index]
index += 1
return odds
You use an array called odds to store the odd numbers, to get the indexes you can create instead an array to store the indexes of the odd numbers, which I called odds_idxs. It should look something like this:
num_list = [0, 3, 2, 3, 4, 7, 6]
def position_of_odds(num_list):
odds_idxs = []
length = len(num_list)
index = 0
while index < length:
if num_list[index] % 2 != 0:
odds_idxs = odds_idxs + [index]
index = index + 1
return odds_idxs

Need to remove every third element in a list of 10 elements - getting index error

I keep getting IndexError: list assignment index out of range. My logic is as follows: The print(x) shows that 6 is printed out before getting the error. Working through the code logically, 6 % 4 == 0 is true, so the code should delete numbers[6 - 1] which is numbers[5]. After that, x is incremented to 7, and the loop will not iterate again.
Can someone please point out where I am incorrect? TIA.
# create list from user specifications
numbers = []
size = int(input("Enter the number of elements: "))
for i in range(0, size):
numbers.append(int(input("Enter an element: ")))
# Iterate through each element. If an elements index is a multiple of 3,
# delete it.
x = 1
while x <= size:
print(x)
if ((x) % 3) == 0:
del(numbers[x - 1])
x = x + 1
print("The list is: ")
print(numbers)
The problem is that the array changes size during the loop. When the index is indeed a multiple of three, the del operation removes the element from the array, thus numbers no longer have a size of size, but your index variable x will still go up to the value of size-1 which is above the last index of your modified array.
An easy way is to build a copy of the list instead of removing elements from it, and ignoring all elements with index multiple of 3.
# create list from user specifications
numbers = []
size = int(input("Enter the number of elements: "))
for i in range(0, size):
numbers.append(int(input("Enter an element: ")))
# Iterate through each element. If an elements index is a multiple of 3,
# delete it.
x = 1
filtered = []
while x <= size:
print(x)
if not ((x % 3) == 0):
filtered.append(numbers[x-1])
x = x + 1
numbers = filtered
print("The list is: ")
print(numbers)
When you delete an item in a list, the remaining items shift left, changing their index. After the first delete, you either have to change your index value or use a different technique completely. Python is well suited for filtering lists with "comprehensions". Use that, and the enumerate function that will emit the values plus their index, and you can simplify this greatly.
numbers = [1,2,3,4,5,6,7,8,9,10]
numbers = [value for index, value in enumerate(numbers, 1) if index % 3]
print(numbers)

Reverse a specific slice of a list in Python

I am trying to write a function that will receive a list and will return a list containing inverted elements between even and odd index. For example:
IP : [1,2,3,4]
OP : [2,1,4,3]
I don't understand why I get an IndexError: list index out of range error with the following code:
def mixed(list):
x = 0
y = 2
l = []
for element in list:
mod_list = list[x:y]
l.append(mod_list[1])
l.append(mod_list[0]
x += 2
y += 2
return l
The l.append(mod_liste[1]) seems to be the issue...
You can use built-in functions and slicing for that:
from itertools import chain
L = [1,2,3,4]
list(chain(*zip(L[1::2],L[::2]))) # [2,1,4,3]
If you don't want to use build-in function. Just make your loop stop when y is greater than list length. Make check for odd list.
def mixed(list):
x = 0
y = 2
l = []
for element in list:
mod_list = list[x:y]
l.append(mod_list[1])
l.append(mod_list[0])
x += 2
y += 2
if y > list.__len__() and list.__len__()%2 == 0:
break
elif y > list.__len__() and list.__len__()%2 != 0:
l.append(list[y-2])
break
return l

What is the way to get the starting and ending index from an input list of unique numbers from 1 to 8 which are not in ascending order

i am trying to find out how i can find the starting and ending index with input constraints that the list should contain non repeating numbers from 1 to 8 only. if the numbers are not in ascending order like [1,2,4,5,3,7,6,8], starting index and ending index should be 2 and 6. My code is below
x = [int(i) for i in input().split()]
k = len(x)
for i in range(len(x)):
if x[i] != i+1:
print(i)
break
for i in range(k-1,0,-1):
if x[k-1] != i+1:
print(i)
break
k -=1
So you are trying to find the earliest index that conforms to ascending order, from both ends of the list.
You can use a list comprehension to check if each element is what it is supposed to be
x = list(map(int, input.split())) # another way to process the input
is_correct = [e == i+1 for i, e in enumerate(x)] # returns a boolean list
start = is_correct.index(False)
end = len(x) - is_correct.reverse().index(False) - 1

How can I find the sum of numbers in a list that are not adjacent to a given number?

Given a list of integers and number, I want to find the sum of all numbers in the list such that numbers and before and after a given number are not added. The given number should also be excluded from the numbers used for the final sum.
Examples:
mylist=[1,2,3,4]
number=2
#output is 4
mylist=[1,2,2,3,5,4,2,2,1,2]
number=2
#output is 5
mylist=[1,7,3,4,1,7,10,5]
number=7
#output is 9
mylist=[1,2,1,2]
number=2
#output is 0
In the first example, only the number 4 is not adjacent to the number 2. Thus the sum is 4. In the last example, no numbers meet the criteria so the sum is 0.
This is what I tried:
def add(list1,num):
for i,v in enumerate(list1):
if v==num:
del list1[i-1:i+2]
print list1
add([1,7,3,4,1,7,10,5],7)
However, my code only works for first and third example.
I worked through your code and here is a working solution:
def check_around(array, index, num):
return True if array[index - 1] != num and array[index + 1] != num else False
def get_result(array, num):
arr = []
for i, number in enumerate(array):
if number != num:
if i == 0 and array[1] != num: # Beginning of list
arr.append(number)
elif (i > 0 and i < len(array) - 1) and check_around(array, i, num): # Middle of list
arr.append(number)
elif i == len(array) - 1 and array[i-1] != num: # End of list
arr.append(number)
return arr
test = [([1,2,3,4], 2),
([1,2,2,3,5,4,2,2,1,2], 2),
([1,7,3,4,1,7,10,5], 7),
([1,2,1,2], 2)]
for (arr, num) in test:
res = get_result(arr, num)
print(f'output is {sum(res)}')
#output is 4
#output is 5
#output is 9
#output is 0
The idea is to create a temp array that saves items that do belong in the summation. Otherwise, we ignore them.
I tried all the tests you gave and it seems to be working fine. Hope this helps.
Get the indexes of the element into a list. +1 and -1 to those will give you indexes of 'before' and 'after' elements. Then take the sum avoiding elements in all these indexes.
list=[1,2,2,3,5,4,2,2,1,2]
number=2
#get all indexes of that number
list_of_indexes=[i for i,x in enumerate(list) if x==number]
#no need to remove -1 if there b'coz we are going to enumerate over 'list'
before_indexes=[i-1 for i in list_of_indexes]
#no need to remove len(list) index if present
after_indexes=[i+1 for i in list_of_indexes]
#might contain duplicate values but no problem
all_indexes_to_avoid=list_of_indexes+before_indexes+after_indexes
sum=sum([x for i,x in enumerate(list) if i not in all_indexes_to_avoid ])
print(sum)
Output
5
Why not just use a if statement and generate a new list instead of removing from the list?
def add(list,num):
j=0
new_list=[]
for i in range(len(list)):
if (i<len(list)-1 and list[i+1]==num) or list[i]==num or list[j]==num:
pass
else:
new_list.append(list[i])
j=i
print(sum(new_list))
print(new_list)
return sum
add([1,2,3,4],2)
add([1,2,2,3,5,4,2,2,1,2],2)
add([1,7,3,4,1,7,10,5],7)
add([1,2,1,2],2)
OUTPUT
4
[4]
5
[5]
9
[4, 5]
0
[]

Categories