index 1 / 2nd list item being skipped for no apparent reason
<p>I have a function that takes a list and removes (one instance of) the smallest and largest elements, then takes the average of the remaining elements.
Running it doesnt bring up any errors, although on checking the results I realised they were incorrect.
Here's the program:</p>

<pre><code>def centered_average(x):
    x.sort()
    y = 0
    for i in x:
        if x.index(i) == 0 or x.index(i) == (len(x)-1):
            print(i, "is being removed")
            x.remove(i)
            i +=1
        else:
            y += i
            print(i, "is being added")
    return (y / len(x))

def average(x):
    return sum(x)/len(x)
</code></pre>

<p>(the print functions were put in for checking)</p>

<p>On putting through a list of</p>

<pre><code>x = [1,2,3,4,5]
</code></pre>

<p>the result was:</p>

<pre><code>1 is being removed
3 is being added
4 is being added
5 is being removed
2.3333333333333335
</code></pre>

<p>therefore, we can assume x[1] is not being used in the function, and I would like to know why.</p>

<p>Thanks in advance for any help.</p>

<p>The issue comes from the <code>for i in x:</code>. When you remove the first element, the second element (2) becomes the first element of the list. This means that on the next iteration, you will look for the second element, and find 3, because the list is now [2, 3, 4, 5].</p>

<p>Instead, you could start by removing the first and last element with <code>x=x[1:-1]</code>. If you've never seen the <code>[i:-j]</code> syntax before, this tells Python to return a list starting at index i, and ending j indices from the end. In other words, this will produce [2, 3, 4] in your example. Afterwards, you could return <code>sum(x)/len(x)</code>.</p>

<p>Note that neither this code, or your original approach, will work on lists of less than 3 elements. When dividing by <code>len(x)</code> in either solution, you will end up dividing by 0.</p>

python list