3

I am trying to delete an item from a list if it is outside the interquartile range from the median.

Here is the list:

l = [69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 87, 89]

The IQR, median and above and below the median are used with import numpy as np

iqr = np.subtract(*np.percentile(l, [75, 25]))
median = np.percentile(l, 50)
minus = median - iqr
plus = median + iqr

The minus number is 69 and the plus is 71 (using the IQR above and below the median)

However, when iterating through the list and trying to delete the items (87, 89) which is above/below the iqr. They are not get removed from the list.

for i in l:
    if i < minus:
        del i
    if i > plus:
        del i

When I print the list, it still shows 87, 89 in it.

Jonathan Davies
  • 882
  • 3
  • 12
  • 27
  • 1
    your loop is not making any changes to the list.. although `i` pops from list, but it's not bounded to list. so `del i` does not touch `l` at all – xbb Dec 11 '14 at 21:29

3 Answers3

1
for  ele in l[:]:
    if ele < minus or ele > plus:
        l.remove(ele)

You must make a copy of l l[:] and mutate the actual list itself using l.remove

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

del is not the operator you're looking for. It is used to remove a reference to an object and is thus useful in garbage collection.

You're probably looking for this:

import numpy as np
l = [69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 87, 89]
iqr = np.subtract(*np.percentile(l, [75, 25]))
median = np.percentile(l, 50)
minus = median - iqr
plus = median + iqr

arr = np.array(l)
arr[ (minus < arr) & (arr < plus)]
Oliver W.
  • 13,169
  • 3
  • 37
  • 50
  • `del` is useful for more than just garbage collection, namely removing an entry from a `dict`. It can be used to delete an entry from a list, too. For example, `x =["a", "b", "c", "d"]`, then `del x[1]` gives `["a", "c", "d"]`. – jme Dec 12 '14 at 02:55
  • @jme, it was only a matter of time before someone would point this out :-) I'd use the explicit method `pop` of both lists and dicts in both cases as they were designed for this purpose. – Oliver W. Dec 12 '14 at 08:48
  • I use each in different scenarios. If I truly want to get rid of the entry, I use `del`. If I want to remove the entry but do something with the value, I use the `pop` method. Seeing a `pop` without assigning the return value makes me uncomfortable, for some reason; `del` seems to me more idiomatic in those cases. Plus `del` provides a concise way to delete slices, like `del x[2:4]`, which, as far as I'm aware, can't be done with a method of a list or dict container. – jme Dec 12 '14 at 16:28
  • @jme, good use case, hadn't considered that! – Oliver W. Dec 12 '14 at 16:33
1

just convert it to a numpy array and then math from there:

l = np.array(l)
l[(l >= 69) & (l <= 71)]

that's it.

acushner
  • 9,595
  • 1
  • 34
  • 34