FAQ: Code Challenge: Loops - Delete Starting Even Numbers

Switching places did work (thanks a lot!) but I don’t know what do you mean by that sentence.

2 Likes

Examine the error message.

What triggered it?


Consider,

>>> a = []
>>> a[0] = 1
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    a[0] = 1
IndexError: list assignment index out of range
>>> 

Testing the length first short circuits the AND logical expression. The second (accessing) operand is never evaluated.

Is it because in the case of the empty list modulo operand is trying to divide a 0 (empty list) by 2?

It never makes it that far. Python is being told to access a non-existent element. It refutes that order by delivering an exception notification.

while lst[0] % 2 == 0
          ^
          |
       accessor
1 Like

I think I get it now. In case of your example you are trying to set the [0] index element to one but since the list is empty it doesn’t have index [0] hence the error, right?

Thank you so much, you’ve been really helpfull :slight_smile:

You’re welcome!

Exactly. Now we understand the error message and its cause. The empty list. By testing for the empty list first, we ensure that at least one element exists when we test the parity of its contained value.

while len(lst) and not lst[0] % 2:

Disclaimer

This is not to suggest a better solution, only to demonstrate order in logic.

My own approach to this problem was to simply look for the first odd value and capture its index. The return is a slice beginning from there.

How did you do it? With a continue statement?

Because we are given a list, we know it is enumerable (can be indexed). Python gives us an iterator for that purpose… enumerate().

It’s very likely that the concept of iterators has not yet come up, so this demonstration is by no means a suggested solution, at this point. Worthy of consideration, though, since it hints at the algorithm.

>>> def f(s):
	for i, x in enumerate(s):
		if x % 2: return s[i:]
	return []

>>> f([2, 4, 6, 8, 10])
[]
>>> f([2, 4, 6, 8, 10, 1, 2, 3, 4, 5])
[1, 2, 3, 4, 5]
>>> 

As for using continue,

>>> def g(s):
	for i in range(len(s)):
		if s[i] % 2 == 0: continue
		else: return s[i:]
	return []

>>> g([2, 4, 6, 8, 10, 1, 2, 3, 4, 5])
[1, 2, 3, 4, 5]
>>> 

Be careful how you use it, is all one can offer by way of advice. We must screen our logic vigorously to spot the edge cases.

2 Likes

Could some one here correct me on my logic…

def delete_starting_evens(lst):
while (len(lst) > 0 and lst[0] % 2 == 0):
lst = lst[1:]
return lst

If I am understanding correctly here, the while loop will run as long as the length of lst is grater than 0 AND lst index 0 must be must have a remainder of zero (meaning it is an even.
If both of these conditions are true, then we set the “variable lst” to the value of the the “original lst” beginning from index 1 till the end.

My question is how or what exactly is telling it to remove the other numbers .

shouldn’t we have a statement that is removing the numbers?

Any help or clarification will be greatly appreciated.

If you’ve accounted for everything else then doesn’t this look like something is being changed?

lst = ...

especially since that’s the only thing that is in the loop, it would have to change things related to the condition or the condition’s outcome would never change

Hello! So I’m kind of confused by why my code isn’t working.

Here is what I had:

def delete_starting_evens(lst):
while lst[0] % 2 == 0:
return lst[1:]

And this was my output:

[8, 10, 11, 12, 15]
[8, 10]

I’m just confused as to why the 8 and the 10 were not removed from both lists. Based on my understanding of while loops, aren’t they supposed to keep executing until the condition is no longer met? But the numbers 8 and 10 fulfill the condition that I made in the second line of my code. So why is the loop only executing once?

What I thought it would do is the following: constantly check the number in lst[0] to see whether it was even, return a new list, and then repeat the same process until we ended up with an odd number in position lst[0].

return in a loop will exit the function before the list is fully iterated.

But it isn’t. So, why is that? Your understanding of a while loop is more or less correct, but something is causing the loop to cease during the first iteration. There is only one line of code in the loop. Which of the things in that line of code could be causing the behavior?

OHHHH okay I completely forgot about that. Thank you!

mtf told me why it specifically didn’t work, but thank you so much for your reply! I appreciate how you tried to get me to think more about what could be going wrong with my code. I’ll try and think some more about what I should add to get the right answer.

Thanks again!

1 Like

Hello, newbie here!

This was my solution to this exercise:

def delete_starting_evens(lst):
  new_list = []
  index = 0
    for number in lst:
      if number % 2 == 0:
        index += 1
      else:
        break
  new_list = lst[index:]
  return new_list

It worked, spat out the correctly trimmed list, spat out an empty list for the all even example (which I assume counts as “working”), and was accepted as correct… but reading the associated forum threads is making me think I didn’t go about it the right way or possibly cheated somehow, by not actually removing the elements from the original list. Is what I did OK?

There’s no reason to modify the original, but if you did, then it probably shouldn’t be returned because the caller already has access to it. Repeatedly removing the first value is also a really bad idea since the list has to be rebuilt each time one does that, so if one were to modify the original value then it should be done all at once by moving values starting from the first odd to the front of the list and then resizing it.

#Write your function here
def delete_starting_evens(lst):
  while (len(lst) > 0 and lst[0] % 2 == 0):
    lst = lst[1:]
  return lst

#Uncomment the lines below when your function is done
print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
print(delete_starting_evens([4, 8, 10]))

I could get the idea of the solution code when dealing with the first print statement. But when dealing with the second print statement the last stage of the iteration is very tricky to understand why it is returning .
The last stage of the iteration I meant by is when the lst become [10] by the end of the second iteration. As lst with its one element 10 has satisfied the while statement the second step is lst = lst[1:]. But lst currently only has one element and that means the index we can take from the list is only 1. How can lst[1:] can return when there is nothing after index 0??

1 Like

Hi, I just want to share my code here,
I implemented this using boolean short-circuiting:

def delete_starting_evens(lst):
  while len(lst) and not (lst[0] % 2):
    lst.pop(0)
  return lst
1 Like
#Write your function here
def delete_starting_evens(lst):
  for index in range(len(lst)):
    while lst[index] % 2 == 0:
      lst = lst[index+1:]
      if lst[index] % 2 != 0:
        break
    return lst
     

#Uncomment the lines below when your function is done
print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
print(delete_starting_evens([4, 8, 10]))

Hi, could someone tell me the problem with my code? Thank you