FAQ: Code Challenge: Loops - Odd Indices

2 posts were merged into an existing topic: Can I use index() for the loop challenge?

2 posts were split to a new topic: Did I loop correctly? - Code Challenge

2 posts were split to a new topic: Index out of range?

5 posts were merged into an existing topic: What is the format for range and what is an odd index?

3 posts were merged into an existing topic: What is the format for range and what is an odd index?

4 posts were split to a new topic: Using list comprehension

2 posts were split to a new topic: Code Challenge - Appending index

2 posts were split to a new topic: How could I improve this comprehension?

2 posts were merged into an existing topic: How can I obtain just the odd indices of a list?

2 posts were split to a new topic: Why do I get an index error with this code?

def odd_indices(lst):
new_list =
i = 0
while i <= len(lst):
if lst[i] % 2 == 1:
new_list.append(lst[i])
i += 1
return new_list

Why this function does not work?

That line does not test the index, but the value at that index. It should be checking if the index is odd, and capture the value, whatever it is, at that index.

if i % 2:
    n.append(lst[i])

So, I already apologize before hand if this question is super dumb since I’m 7 days into coding. But I figured out this way to solve this exercise and it does give the appropriate result, but prints an error (local variable ‘new_lst’ referenced before assignment). I don’t understand why that should be a problem, since the end result is the one desired. This is my piece of code:

def odd_indices(lst):
  substract = len(lst)
  for index in range(1, len(lst), 2):
    lst.append(lst[index])
    new_lst = lst[substract:]
  return new_lst
  

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

I’ve seen the solution now and it is more elegant and see it is a better way to have that output, but still don’t know why the first one should be wrong.

Would anybody be nice enough to enlighten me. Thanks a lot!!

Does the said solution employ a range object? If so, think of that object as a sort of mask that exposes some elements, but not others.

Let’s visualize…

[7, 4, 3, 5, 9, 2, 6, 1, 8]

The disorder of the above is preserved in the list, which is ordered. The elements in the list all have an index. Being as they are integers, half will be odd and half will be even, give or take.

 -     -     -     -     -    =>  even indices
[7, 4, 3, 5, 9, 2, 6, 1, 8]
    .     .     .     .       =>  odd indices

Using range to build a template from the above information permits us to grab only the ones we want.

range(0, len(...), 2)    =>  evens
range(1, len(...), 2)    =>  odds

You’d want to consider the input used at the time of the crash, not the one where you got a successful result. The error message you’re getting is saying something about what the problem is, how could that possibly happen for your code, what would necessarily have to happen to cause that? What would be required for that code to not define that variable, what would cause that part of the code to not run at all?

Also, seems like you’re making a whole lot of copies of parts of the list, probably not so great of a strategy.

As for neat strategies, how about:

chunk it into groups of 2
drop 1 from each chunk
concat

1 Like

Thanks for the explanation. The solution provides an empty list before running the range, so then adds the selected items provided to that empty list and then returns that new list (instead of substracting the amount of elements equal to the lenght of the original list as I did. It goes like this:

def odd_indices(lst):
  new_lst = []
  for index in range(1, len(lst), 2):
    new_lst.append(lst[index])
  return new_lst

Anyway, and this might be me still grasping too little, I don’t understand why providing the new_lst before the for loop in this case does not bring any error.

Even if you don’t have the time to answer this further quiestion, thanks a lot for the previous thorough explanation!

1 Like

We need to define the object before we start assigning to it, and once inside the loop we want the object to be persistent, as in keeping its values as they accumulate. It would make little sense to define the object inside the loop. We’d end up with length one.

Thank you! I.m facing a similar situation with another exercise.

1 Like

Hi, need help with the code I wrote for this particular exercise

#Write your function here
def odd_indices(lst):
  empty_list = []
  for i in lst:
    while (not i < 0) and i%2 != 0 and i <= (len(lst)-1):
      empty_list.append(lst[i])
      i += 2
  return empty_list

#Uncomment the line below when your function is done
print(odd_indices([4, 3, 7, 10, 11, -2]))

This returns me with [10, -2]