2

I'm currently doing a homework question:

Write and test a function modify_list that, given a list of floating point numbers as a parameter, computes the average of the values in the list and removes all values greater than the average from given list.

So far my code looks like this:

def modify_list(L):

    average = sum(L) / (len(L))
    j=0
    for J in L:
        if J>average:
            L.pop(J)
        else:
            j=j+1

L=[3,12,2,21,2,1,2]

modify_list(L)

print(L)

So far I have my list that is being passed to my function modify_list that then computes the average of my list. Then I have a for loop that takes each value in the list and compares it to the average. If the value within the list is greater than the average then it gets deleted through L.pop(J). The only problem is my error, which is:

Traceback (most recent call last):
  File "/Users/nathan/CP/test/src/test.py", line 22, in <module>
    modify_list(L)
  File "/Users/nathan/CP/test/src/test.py", line 17, in modify_list
    L.pop(J)
IndexError: pop index out of range

Should I maybe try a while loop instead of a for loop?

I created a while loop and it works perfectly... although L.remove(i) worked perfectly as well. I still don't understand why L.remove(i) is a bad idea. This is my new code:

1 def main(L):

2 average = sum(L) / (len(L))

3 i=0

4 while i

5 if L[i]>average:

6 L.pop(i)

7 else:

8 i=i+1

9

10 L=[3,12,2,21,2,1,2]

11 main(L)

12 print(L)

CP_nate
  • 41
  • 6
  • 4
    You're changing the length of the list while iterating over it - this is a **very bad idea**. See e.g. http://stackoverflow.com/q/1798796/3001761 – jonrsharpe Mar 12 '15 at 16:49
  • @but am now getting: TypeError: 'list' object is not callable because L(i), insead use this, L[i] – jatinkumar patel Mar 12 '15 at 17:00

2 Answers2

-1

In addition to @johnsharpe's very good point, pop take the index of the element you want removed, while you are passing it the value.

If instead you iterated over the indices of the list, you can both use pop and avoid modifying while iterating. But be careful: when you remove something from the list, it gets smaller and some indices now have new values in them.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
-1

Along with jonrsharpe's comment, the issue is that you are using pop() as if it removed the item J, but the method is actually designed to remove the item at that index.

For instance, when you find that 21 is above the average and try to remove it with L.pop(21), it looks for the 21st item in the list. Since there are not that many items, you get an IndexError.

Use L.remove(21) instead of pop() to fix this. Remove is similar to pop(), but it removes the first item in the list with the given value, as you are trying to do.

Alecg_O
  • 892
  • 1
  • 9
  • 19
  • How does this address the problem of modifying a list while iterating over it? – Scott Hunter Mar 12 '15 at 16:55
  • It doesn't, but that's not his problem in this case. Once he fixes his main problem, he can look at jon's link for a more detailed reasoning for why this is a bad idea. – Alecg_O Mar 12 '15 at 16:56