1

I have been set a small task for my CS class in which I have to write a method in Python to delete the items at prime index locations within a list, up to index 50.

I have attempted to produce the method, as shown below, however when i attempt to print the list at the end of the method, it should return the list with the values in prime index locations deleted, however it is simply just returning the full list (numbers 1 to 50).

My function:

def listDelete(list):
    for i in list:
        if i %2 != 0 & i % 3 != 0:
            del list[i]
return list

And I call the function by using:

listDelete(range(1,50))

I am very new to python so apologies if this is a very simple fix, or glaring error,but any help would be much appreciated!

freshwaterjoe
  • 101
  • 2
  • 15

5 Answers5

1

Instead of del, you should use pop method of List class. In order to use pop, you need the index of the list element which you can get in your for loop using enumerate:

def listDelete(list):
    for index, value in enumerate(list):
        if value % 2 != 0 and value % 3 != 0:
            list.pop(index)
    return list

print listDelete(range(1,50))

result:

[2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 26, 27, 28,
 30, 32, 33, 34, 36, 38, 39, 40, 42, 44, 45, 46, 48]

That being said, your logic does not find all the prime indices, for example 25 is not prime but it is not divisible by either 2 or 3.

Selcuk
  • 45,843
  • 11
  • 87
  • 90
  • I forgot to add that in the criteria for the function, it is the del statement that must be used, apologies. But thank you for pointing out the flaw in my logic- rookie error! – freshwaterjoe Feb 19 '15 at 17:41
  • `del list[index]` does the same thing as `list.pop(index)`, except that it isn't an expression and doesn't return the value at the index. Also, there's a problem due to deleted cells shifting the indices of later cells. – user2357112 supports Monica Feb 19 '15 at 20:52
0

There are two main problems with the code you've written. Python as both logical and bitwise and operators, and and &. You might want to read about the difference.

Also you're looping over a list and changing that same list in the loop, that's not a good idea (take a look at the last example in this section). How about instead of changing your input list, simply create a new list with non-primes and return the new list?

One last thing, in the question you say that you want to delete the values at prime indices, but you're checking "primness" on the values of the list, not the indices (i say "primeness" because you're not really checking primeness but I think you know that).

Bi Rico
  • 23,350
  • 3
  • 45
  • 67
0

how about this?

import numpy as np

def listDelete(list):
    for i in list:
        if (i %2 != 0 and i % 3 != 0):
            list[i] = 0
    return list[np.nonzero(list)]

which you can call as:

listDelete(np.arange(1,51))
user14241
  • 585
  • 1
  • 5
  • 17
  • 2
    Since the question doesn't mention numpy it might be best to come up with answers that do not use numpy. This can easily be done without numpy and we cannot know whether the instructor would accept a solution using outside libraries. Also since this is a homework problem, it might be best not to completely give away the answer. – Bi Rico Feb 19 '15 at 17:52
  • Sorry I missed this was a homework question. My answer was pretty bad anyway, I've updated it a bit. But yeah, probably not is his interest to turn in stuff using numpy without instructed. That would be pretty good evidence he got his answer of the internet. – user14241 Feb 19 '15 at 17:58
0

So if I'm reading you correctly, you need to remove all items in a list that have an INDEX that is a prime number. If so, you want this:

def deletePrimeIndex(l):
    return [value for index, value in enumerate(l) if index > 1 and not all(index % i for i in range(2, index))]

If you want the value to not be prime:

def deletePrimeValue(l):
    return [value for value in l if value > 1 and not all(value % i for i in range(2, value))]

Output:

In  [1]:  print deletePrimeIndex(range(1, 50))
Out [1]:  [5, 7, 9, 10, 11, 13, 15, 16, 17, 19, 21, 22, 23, 25, 26, 27, 28, 29, 31, 33, 34, 35, 36, 37, 39, 40, 41, 43, 45, 46, 47, 49]

In  [2]:  print deletePrimeValues(range(1, 50))
Out [2]:  [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49]

Note: When you use range(1, 50) every value will be one digit greater than it's index. IE: range(1, 50)[0] would be 1 not 0.

Also, both of these do technically return new lists.

Daniel Timberlake
  • 1,099
  • 6
  • 15
0

You may want to add the requirement to use del (which you mentioned in your comment) to the question.

Anyway, here's how I'd do it.

def primesTo50():
    '''Generator for prime numbers up to 50'''
    primes = {2, 3, 5, 7, 9, 11 , 13 , 17, 19, 23, 29, 31, 37, 41, 43, 47}
    yield from primes

def delIndices(L, indices, maxIndex = None):
    '''Delete indices of the list up to list length or to the 
    max index if it is provided'''
    if maxIndex is None:
        maxIndex = len(L) - 1
    indices_set = set(sorted(indices)) #don't try to delete the same index twice
    for i in reversed(range(maxIndex + 1)): #must delete in reverse order
        if i in indices_set: #check if i is in the indices to be removed
            try:
                del L[i]
            except IndexError: #ignore error from trying to delete invalid indices
                pass
    return L

#testing
print(delIndices([1,2,3,4], primesTo50(), 50)) # [1, 2]
print(delIndices([1,2,3,4], (0,100), 200)) # [2,3,4]

You could also do your prime number generator something like this:

def primes(max):
    '''Generator for prime numbers up to (not including) max'''
    r = range(max)
    for i in r:
        divisors = range(2, i)
        prime = True
        for d in divisors:
            if r%d == 0:
                prime = False
                break
        if prime:
            yield i

There are many other much better solutions to this problem; I just whipped this up real quick (and haven't tested it - I'm sure it's very slow). Generating prime numbers is its own field in number theory so IMO you're much better off with just listing the primes up to 50 as I did above.

Community
  • 1
  • 1
Rick supports Monica
  • 33,838
  • 9
  • 54
  • 100