Why do I have to include the `/2` in the `int()`?


#1

Middle Item

I am a little embarrassed to say this but I have come back to this challenge every day for a week and still can’t remember the solution the next day. I think my problem is that I don’t understand why in:

sum = lst[int(len(lst)/2)] + lst[int(len(lst)/2) -1]

this line of code, the int() is not only for the len(lst). Why do I also have to include the “/2” in the int… and even further, why NOT include the “-1”? Maybe if I understood the reason, I would be able to rationalize it and remember.


FAQ: Code Challenge: Lists - Middle Item
FAQ: Code Challenge: Lists - Middle Item
#2

In this mockup, think of each [_] as an element in a list.

[
  [_],
  [_],
  [_],
  [_],    #  m - 1
  [_],    #  m
  [_],
  [_],
  [_]
]

The length is 8. To find the approximate middle of the list we divide by 2, which gives 4. We know that lists are zero-indexed so this means the fifth element is part of the middle pair (even length lists need two indexes). So if m = len(lst) // 2, then the middle pair is at lst[m - 1] and lst[m].

Note that when the list is even length, the division results in an integer (or integer equivalent), but when the length is odd, the division will result in a float. That is why we need the int() value, since indexes must be integer. Above I use the integer (floor) division operator rather than the int() constructor.

9 / 2     =>  4.5
9 // 2    =>  4

In Python 3, all division returns a float quotient, and since 4.0 is a float, it cannot be used as an index.

8 / 2     =>  4.0
8 // 2    =>  4

#3

I think it was the last part, the fact that all division leads to a float, that got me. I now remember them teaching that in the very beginning! I need to make sure to add it to my notes. Thank you so much for the thorough explanation!


#4

Hi,

I understand the idea. I tried to do this only by floor division. In the end I get also minus -7 . But with this code:

#Write your function here
def middle_element(lst):
  if len(lst) % 2 == 1:
    index = (len(lst) - 1) / 2
    mid_element = lst[index]
    return mid_element
  
  else:
    index1 = (len(lst) // 2) - 1
    # (6.0 / 2) - 1 = 2
    index2 = (len(lst) // 2)
    # (6.0 / 2) = 3
    average = (lst[index1] + lst[index2]) // 2
    return average

#Uncomment the line below when your function is done
print(middle_element([5, 2, -10, -4, 4, 5])) # index 2 and 3

the console shows “-7” but I get an error message “list indices must be integers or slices, not float”

is my assumption right?

 index1 = (len(lst) // 2) - 1
    # (6.0 / 2) - 1 = 2
    index2 = (len(lst) // 2)
    # (6.0 / 2) = 3

#5

I am sorry I was looking at these lines yesterday and today again. Now I see the mistake:

def middle_element(lst):
  if len(lst) % 2 == 1:
    **index = (len(lst) - 1) / 2** # should be //
    mid_element = lst[index]
    return mid_element

#6

Not sure, why, -1?

lst = [2, 4, 6, 8, 10, 12, 14]
n = len(lst)            # 7    note that n is an integer
m = n // 2              # 3    index is an integer
v = lst[m]              # 8    value at index


lst = [2, 4, 6, 8, 10, 12, 14, 16]
n = len(lst)            # 8    note that n is an integer
m = n // 2              # 4    index is an integer
v = lst[m]              # 10   value at index
u = lst[m-1]            # 8    value at index - 1
x = float(u + v) / 2    # 9.0  average of u and v

#7

In that case -1 is necessary if if I just use normal “/” division. in case of floor division it’s not necessary.


#8

It’s arbitrary, and basically fudging the outcome. We know that for an even list, the length divided by 2 gives the upper index of the middle pair of elements. The lower index is 1 less.

For an odd length, the middle element is the integer quotient of dividing by 2. We don’t need to subtract 1. Bear in mind zero-indexing.

9 / 2 => 4.5

We want an integer, so if not floor dividing, then one supposes we can subtract 1 then divide; that will work. We could also cast the quotient to integer,

int(9 / 2)

Floor division is the simplest, however.


#9

once I had the answer to this problem:

#Write your function here
def middle_element(lst):
if len(lst) % 2 == 0:
sum = lst[int(len(lst)/2)] + lst[int(len(lst)/2) - 1]
return sum / 2
else:
return lst[int(len(lst)/2)]

#Uncomment the line below when your function is done
print(middle_element([5, 2, -10, -4, 4, 5]))

Answer is -7

I could go back and follow the code that got there. I found “middle_element” confusing.
Why not just def it as the median? It would have made it easier to understand what to do and how to get there.


#10

Because it is not the median (a statistical value) we are after, only the middle one or two elements of an unsorted list. It could be preparatory for a median problem, but is not one.