1

I'm trying to iterate through a list (range entered by user), at first assume that all numbers are prime (P), and have the program iterate through the list. When the element in the list is P, I want to iterate through all multiples within the range and change them to N. When the element is N, I want the program to move onto the next number (I set 0 and 1 to not prime, as they are exceptions). I'm running into an issue with indexing however, I get the error:

 list1[number1] = 'N'
IndexError: list assignment index out of range

When I run the program I have. Here is the code:

# input

n = int(input("Enter a positive integer greater than or equal to 10: "))

while n < 10:
    print ("Invalid! Try again")
    int(input("Enter a positive integer greater than or equal to 10: "))


# create list
new_n = n + 1

list1 = ['P'] * new_n


# set non prime
list1[0] = 'N'
list1[1] = 'N'

# set up loop

counter = 0 
for x in list1:
    counter1 = 2
    if list1[counter] == 'P':
        for y in list1:
            number1 = counter * counter1
            list1[number1] = 'N'
            counter1 += 1
            counter += 1 
    else:
        counter += 1 

Any help would be appreciated! Thanks.

Danny Garcia
  • 227
  • 3
  • 15
  • 2
    Hint: use `enumerate()`, not a raw index loop. It'll give you access to both the element and its corresponding index at the same time. – Akshat Mahajan Apr 24 '16 at 23:05
  • @AkshatMahajan thanks! i'm doing that now. But if I have enumerated the list, how could I index just the number corresponding to an element in that list. For example in an enumerated list like (2, P) how would I index just the 2 as an int? – Danny Garcia Apr 24 '16 at 23:35
  • You want to do `for index, item in enumerate (list1)` to get access to the corresponding index of `item`. – Akshat Mahajan Apr 24 '16 at 23:37
  • There is nothing in your code to stop the program from trying to set values outside of the user-specified range to 'N'. For example, if the user chooses 11, if `counter` is 2 and `counter1` is 6, the algorithm will try to set element 12 to 'N'. However, as `len(list1)` is 11 in this case, you get an error. Looks like you need to add constraints on your counters. – Zach Fox Apr 24 '16 at 23:39

3 Answers3

2

In your loops, you're setting only squared value as non prime because you iterate counter in counter1's loop.

Then you have to check if number1 is lesser than the size of list1.

You also have to put counter+=1 outside else statement. Otherwise you'll set only multiples of 2 (once you withdraw counter+=1 from counter1's loop).

So this code works:

# set up loop
counter = 0
for x in list1:
    counter1 = 2
    if list1[counter] == 'P':
        for y in list1:
            number1 = counter * counter1
            if number1 < len(list1):
                list1[number1] = 'N'
                counter1 += 1
    counter += 1

Besides, you should simplify your code using enumerate and range:

# set up loop
for i, val in enumerate(list1):
    if val == 'P':
        for j in range(2, len(list1)):
            if i*j < len(list1):
                list1[i*j] = 'N'
            else:
                break

Here's the result for n = 12:

 Enter a positive integer greater than or equal to 10: 12
 ['N', 'N', 'P', 'P', 'N', 'P', 'N', 'P', 'N', 'N', 'N', 'P', 'N']

Edit: Put counter+=1 outside else statement

cromod
  • 1,421
  • 9
  • 25
1
list1[number1] = 'N'
IndexError: list assignment index out of range

That means that number1 is a bigger number than the total amount of items in the list.

The problem is in the line number1 = counter * counter1. Lets say are 10 items in list1, by the time you got to using the number 10 as the counter you are going to be trying to access the 100th item in the list even though there are only 10 items in there. (counter * counter1 or 10 * 10 = 100 (actually the counter starts at 2 so it would be an even bigger number, but you get the point))

Also a nice little hint. Implementing a Sieve of Eratosthenes algorithm instead will greatly speed things up.

Community
  • 1
  • 1
wp-overwatch.com
  • 6,475
  • 3
  • 34
  • 43
0

You may update your code like this:

# set up loop
for counter in range(len(list1)):
    if list1[counter] == 'P':
        number1 = 2 * counter
        while number1 < new_n:
            list1[number1] = 'N'
            number1 += counter
nino_701
  • 604
  • 3
  • 13