List indexes cannot have floats

This code ran in Atom but will not run in the python text editor. Anyone know why?

def middle_element(lst):
if (len(lst) % 2) != 0:
return lst[((len(lst) - 1) / 2)]
if (len(lst) % 2) == 0:
return (lst[len(lst) / 2] + lst[(len(lst) / 2) - 1]) / 2

TypeError: list indices must be integers or slices, not float

3.5.2 (default, Nov 12 2018, 13:43:14)

In Python 3, this will be a float, unlike Python 2. Try using floor division, // 2.

def middle_element(lst):
  if (len(lst) % 2) != 0:
    return lst[((len(lst) - 1) // 2)]
  if (len(lst) % 2) == 0:
    return (lst[len(lst) // 2] + lst[(len(lst) // 2) - 1]) / 2
1 Like

def middle_element(lst):
if len(lst) % 2== 0:
average_middle_numbers = lst[len(lst)/3] + lst[len(lst)/2]
return average_middle_numbers / 2
elif len(lst) % 2 !=0:
return lst[(2*len(lst)-1)]

I get:
File “script.py”, line 5, in middle_element
average_middle_numbers = lst[len(lst)/3] + lst[len(lst)/2]
TypeError: list indices must be integers or slices, not float
By the way i fixed it by putting int() but I dont remember when to put the int() command. can someone make refresh knowledge?

The int() function is a constructor that creates an int instance object. When to use it depends upon what data type will be expected in the circumstance. This is one…

lst[len(lst)/3] + lst[len(lst)/2]

In Python 3, division results in a quotient of type, float. However, above we are subscripting a list which requires integer index references. Floats cannot be used as indices.

Hey All,

Can’t quite figure out why I’m still getting the integer, not float error here…

def middle_element(lst):
if(len(lst) % 2 == 0):
lst[int(len(lst)/2) + int(len(lst)/2 - 1)/2]
else:
lst[int(len(lst)/2)]

If this is Python 3.x then it will give a float result to the division by 2. Skip all the integer casting on the components. Get to the end of the math and cast it then.

Thanks for the response! By “Get to the end of the math and cast it then.” Do you mean casting the entire line as an int? e.g.

instead of:

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

Do:

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

What eventually worked for me was…
(1) creating a variable that summed the two components I previously summed as one argument of the lst
(2) adding in “return” after the “else” I missed that before

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)]

thanks!

1 Like

middle_element

I don’t understand why I’m getting an error here (see attached screenshot). The error seems to be about the fact that the indices of a list cannot be floats. However, my second if statement specifies that the code that follows is for indices divisible by two with zero remainder, so they should not result in a float. I don’t understand why my code didn’t work; what am I missing?

In Python 3, all division yields a float quotient.

>>> 6 / 2
3.0
>>> 

Aside

When we see a lot of repetition in the code it becomes evident that abstracting away that code makes everything a lot clearer.

def middle_element(lst):
    if ___ % 2:
        return lst[___]
    else:
        return (lst[___] + lst[___]) / 2

Above we can see the gist of the function with repeated elements removed. Note that len(lst) is repeated five times in your code. We can abstract away that expression by assigning its output to a variable.

n = len(lst)

Run once, use the result multiple times. Notice also how many times your code divides by 2? That operation can also be abstracted away.

m = n / 2

As we know that will produce a float quotient but we can cast that to an integer with the int() constuctor.

m = int(n / 2)

For odd length lists m will be the middle index.

[ ] [ ] [ ] [m] [ ] [ ] [ ]

For an even length list m will be the lowest index in the upper half of the list.

  lower half      upper half
[ ] [ ] [ ] [ ] [m] [ ] [ ] [ ]

That means the other middle element in the pair is at index m - 1.

    [ ] [ ] [ ] [m-1] [m] [ ] [ ] [ ]

This is enough information for us to fill in the blanks in our model…

    if  n  % 2:
        return lst[ m ]
    else:
        return (lst[ m - 1 ] + lst[ m ]) / 2    # will be a float

When we plan ahead, the work gets lighter and mistakes are reduced to a minimum.

Hi,

My question is related to the provided solution line 3 and 4.

Line 3: The ‘if’ statement checks to see if the ‘len(lst)’ is an even number. If this is True we proceed to Line 4.

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

I don’t understand why both ‘int’ are needed. If line 3 is True any number divided by 2 will return an integer.

I don’t understand why the code returns an error if you remove both ‘int’ commands.

Thanks in advance.

In Python 3, all division results in a float. Floats may not be used as indices, hence casting to int of the quotient in each operand.

We can simplify the code, thereby making the operation more transparent…

n = len(lst)
m = int(n / 2)

middle_sum = lst[m-1] + lst[m]

Given that len(lst) and 2 are both integers, we may use floor division to yield an integer result.

 m = n // 2

To arrive at the desired middle, we must take the average of the two terms, and return a float.

 middle = middle_sum / 2

In Python 2 we would need to cast one of the operands to float.

middle = float(middle_sum) / 2

or,

middle = middle_sum / 2.0

So does this mean that adding int() in front of the length always rounds up and not down? For instance, the list length could be 5 in which case divided be by 2 would be 2.5. So int() always convert it to the higher integer i.e. 3 and not 2? Because it is right in the middle

If you’re doing exact math then you shouldn’t be using floats, there would therefore also be no need to convert from float. Stick to integer math. If you end up with a float then the solution isn’t to convert it to int, it’s to not have it in the first place.

1 Like

Think of int() (when used with floats) as a function that returns the integer portion of the float. For positive numbers, this is the “lower” integer, for negative, the “higher” (i.e., closer to zero in each case.)

1 Like

Or, as what it is, a constructor that takes a value and constructs an int object from it, or raises an exception.

1 Like

I was able to get the correct answer, however it won’t let me proceed. Maybe I didn’t do it in the most straightforward way, however I did get -7. Could anyone please tell me what I’m not getting?

def middle_element(lst):
  n_list = len(lst) 
  n_list2e = n_list // 2 - 1
  n_list2o = (n_list / 2) - 0.5
  if n_list % 2 == 1:
    lst_odd = lst[n_list2o]
    return lst_odd
  else:
    lst_even = (lst[n_list2e] + lst[(n_list2e)+1]) // 2
    return lst_even