Odd Indices: Only One Index Returned

Learn Python 3 | Codecademy

For Question 4, the answer I gave below only returns index 3 (10), even though indexes 1, 3, and 5 should satisfy the if statement. I’m not sure what underlying logic I’m missing.

def odd_indices(lst):

  new_lst = []

  for l in lst:

    if l < len(lst) and l % 2 == 1:

      new_lst.append(lst[l])

  return new_lst

#Uncomment the line below when your function is done

print(odd_indices([4, 3, 7, 10, 11, -2]))

The problem here seems to be that you are confusing the actual index of the list with the value that is on that index.

for l in lst:
    print(l)

The above code returns the values stored in the list (4, 3, 7, 10, 11, -2).

if l < len(lst) and l % 2 == 1:

Here you are checking if the value is smaller than the length of the list and if the value is odd. If we were to print the result of the first expression for each value then the following is returned.

(True, 4)
(True, 3)
(False, 7)
(False, 10)
(False, 11)
(True, -2)

As we can see above there are is only 1 value that satisfies the condition to both be smaller than the list and be considered an odd number (value: 3)

new_lst.append(lst[l])

Knowing that only one value satisfies both conditions, we know that the value of l here will be 3. lst[l] returns the value stored in the 3rd index (value: 10) and appends this to the list.

I hope this helps you in figuring out the problem!

Good luck!

1 Like

I suppose I’m confused as to why l in the loop and l in new_lst.append() are interpreted in different ways by the code. If I change new_lst.append() to append l instead of lst[l], it gives me a value of 3, the index, but l in the loop gives me the value stored in index 3, which is 10. Is this just a difference in how loops and functions work? As in, loops pull the value at each index by default, while functions pull the index itself?

def odd_indices(lst):

  new_lst = []

  for l in lst:

    if l < len(lst) and l % 2 == 1:

      new_lst.append(lst[l])

  return new_lst

print(odd_indices([4, 3, 7, 10, 11, -2]))
# This returns 10
def odd_indices(lst):

  new_lst = []

  for l in lst:

    if l < len(lst) and l % 2 == 1:

      new_lst.append(l)

  return new_lst

print(odd_indices([4, 3, 7, 10, 11, -2]))
# This returns 3.

But this code works as it should.

def odd_indices(lst):

  new_lst = []

  for l in range(len(lst)):

    if l % 2 == 1:

      new_lst.append(lst[l])

  return new_lst

print(odd_indices([4, 3, 7, 10, 11, -2]))

So in the first two, when we tell the program to look at each l in lst, it checks the value of l in lst, not the index which l is at, and then runs its command off of that value for each. When we tell it to look at the value of l in range(len(lst)), it associates each number in the range with the index of a given list and then runs its command on the value within that index. Is that right? And loops interpreting a given range as a list is just built into how they work?

Sorry if this is all over the place, I’m jumping back and forth trying to figure this out.

If I change new_lst.append() to append l instead of lst[l], it gives me a value of 3, the index

Actually it is giving you the value of 3, stored at index 1. I would advice you to try this with some different (higher) numbers so you can see what is happening without the confusion that it might be an index.

value_at_index_i = list[i]

The above code returns the value stored at the given index (i) which is illustrated by its output:

for i in range(len(lst)):
    print(i, lst[I])

(index, value)
(0, 4)
(1, 3)
(2, 7)
(3, 10)
(4, 11)
(5, -2)

Now that we know that lst[I] gives the value stored at the given index, we need to have a good look at the following code:

if l < len(lst) and l % 2 == 1:

      new_lst.append(lst[l])

As mentioned lst[i] returns the value stored at given index i so:

lst = [4, 11, 75, 13, 144, 6]
for l in lst:
    # l= 4
    if l < len(lst):
        new_lst.append(lst[4]) #Here we are adding the value of 144 because that is stored at index 4

I hope I have been able to put my thoughts on paper in a semi-understandable way :slight_smile:

For the example range():
The range() function (simply said) returns a sequence of numbers starting at 0 to x-1.

for value in range(4):
    print(value)

0
1
2
3

In most cases this coincides with the indexes of a list so this would lead to:

for value in range(4):
    print(f"lst[{value}]")

lst[0]
lst[1]
lst[2]
lst[3] 

As you mentioned that snippet of code works as it should, and with the explanations above you should now be able to figure out why it indeed works. And no worries… before you know it you can solve this entire assignment in a single line of code :smiley:

1 Like

Thank you for the help! I think I’ve got it now.