Delete Starting Even Numbers - Loops

https://www.codecademy.com/paths/computer-science/tracks/cspath-flow-data-iteration/modules/dspath-python-loops/lessons/python-functions-loops-cc/exercises/remove-even-nums

The question;

Write a function called delete_starting_evens() that has a parameter named lst .

The function should remove element from the front of lst until the front of the list is not even. The function should then return lst .

For example if lst started as [4, 8, 10, 11, 12, 15] , then delete_starting_evens(lst) should return [11, 12, 15] .

Make sure your function works even if every element in the list is even!

My code;

def delete_starting_evens(lst):
  for i in lst:
    if i % 2 == 0:
      lst = lst[1:]
  return lst

print(delete_starting_evens([4, 8, 10, 11, 12, 15])) #returns [12,15]
print(delete_starting_evens([4, 8, 10])) # returns []

My question: Why does 11 get removed from the first function call?

It could be caused by mutating the list you are iterating over. That can often cause problems that we don’t foresee.

What if you found the first odd number and used its index?

>>> lst =  [4, 8, 10, 11, 12, 15]
>>> for i in range(len(lst)):
	if lst[i] % 2:
		break

	
>>> lst[i:]
[11, 12, 15]

.

1 Like

Thank you for the reply. I can’t get it to work but will keep trying.

1 Like

For your code to work properly you have to also add a break, because its a for loop, even if i isnt a even number anymore, it continues looping the list, therefore lst[1:] goes further than 11. Thats why a while loop is recommended for this exercise, it loops till i isnt even anymore and stops by himself. Hope you understand what I mean.

def delete_starting_evens(lst):
  for i in lst:
    if i % 2 == 0:
      lst = lst[1:]
    else:                      #if i % 2 != 0 it stops here and code works now correctly
      break
  return lst

print(delete_starting_evens([4, 8, 10, 11, 12, 15])) #now returns [11, 12,15]
print(delete_starting_evens([4, 8, 10])) # returns []

As an addition, thats my code for this, you can also use list.pop to get rid of the evens:

def delete_starting_evens(lst):
  while lst and lst[0] % 2 == 0:
    lst.pop(0)
  return lst

while lst returns true if lst isnt empty, if lst is empty at the end it returns false and the loop stops.

5 Likes

Hi @lab-xi,

Your for loop iterates through the original list that is passed to the function.

Meanwhile, this statement creates a new list and assigns it to lst

      lst = lst[1:]

However, the for loop continues to iterate through the original list that was passed to it.

The following may illuminate the problem …

def delete_starting_evens(lst):
  position = 0
  for i in lst:
    print("\nTesting position in original list {:d} - Value: {:d}".format(position, i))
    if i % 2 == 0:
      print("{:d} is even - Getting rid of {:d}".format(i, lst[0]))
      lst = lst[1:]
      print("New list: {}".format(lst))
    position += 1
  return lst
print("******************************")
lst = [4, 8, 10, 11, 12, 15]
print(lst)
print(delete_starting_evens(lst))
print("******************************")
lst = [4, 8, 10]
print(lst)
print(delete_starting_evens(lst))
print("******************************")
lst = [4, 8, 10, 11, 12, 15]
print(lst)
print(delete_starting_evens(lst))
print("******************************")
lst = [4, 8, 10]
print(lst)
print(delete_starting_evens(lst))

Output …

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

Testing position 0 in original list  - Value: 4
4 is even - Getting rid of 4
New list: [8, 10, 11, 12, 15]

Testing position 1 in original list - Value: 8
8 is even - Getting rid of 8
New list: [10, 11, 12, 15]

Testing position 2 in original list - Value: 10
10 is even - Getting rid of 10
New list: [11, 12, 15]

Testing position 3 in original list - Value: 11

Testing position 4 in original list - Value: 12
12 is even - Getting rid of 11
New list: [12, 15]

Testing position 5 in original list - Value: 15
[12, 15]
******************************
[4, 8, 10]

Testing position 0 in original list - Value: 4
4 is even - Getting rid of 4
New list: [8, 10]

Testing position 1 in original list - Value: 8
8 is even - Getting rid of 8
New list: [10]

Testing position 2 in original list - Value: 10
10 is even - Getting rid of 10
New list: []
[]
3 Likes

Thank you for the reply - lists returning true/false when not empty/empty is a new trick for me!

No trick, at all. There are no tricks in programming. Just logic which can be spun in many ways.

if lst:

In the above we draw upon the truthiness of the object. Empty objects are not truthy.

0
""
''
[]
{}
()
None

… are all falsy. Demonstrated another way, consider that and is short-circuited on False, so in the following, the first operand will be returned…

>>> () and True
()
>>> {} and True
{}
>>> [] and True
[]
>>> 0 and True
0
>>> '' and True
''
>>> "" and True
''
>>> None and True
>>> 

Notice that the last one has no output. That’s because None has no printable characters, so nothing is outputed, not even a newline.

2 Likes

Thank you for the reply - I can see exactly what is happening with the code in my original post.

If there a way to modify a list passed into a function and have the function use the new modified list for the next iteration of the loop?

Is this what you mean? …

def triple_the_numbers(nums):
    # triple all the numbers in the original list
    for i in range(len(nums)):
        nums[i] *= 3

my_numbers = [7, 4, 9, 8, -3]
triple_the_numbers(my_numbers)
print(my_numbers)

Output …

[21, 12, 27, 24, -9]

Note that the function modifies the original list that is passed to it.

You can also use append or other list methods to modify the original.

1 Like

Ok, so your original example with the break in the loop is still looping the original list, and modifying a new, separate list.

The difference with your code is that the loop is terminating once it reaches an odd number, and therefore not continuing to modify the new list by iterating through the original list. I think I’ve got it now(?). Thanks again!

Quick question:

Can you elebaorate which part of your code is meant to “remove element from the front of lst until the front is odd?”

Is if i % 2 == 0:
lst = lst[1:] ?

Can you help me on that?

Hi @micheledallari940840,

Yes the first line initiates the for loop.

The second line will check if the value at the index (i) currently in the loop is even.

Line 3 states that if it is an even number, lst should now equal lst with the first index (index 0) removed.

Lines 4 and 5 state that if the value of the number at the current index is not even, finish iterating the loop.

1  for i in lst:
2    if i % 2 == 0:
3      lst = lst[1:]
4    else:
5      break

Clear! thanks @lab-xi

1 Like

Hi there,

Thanks for the methods.

I think the hint provided by codecademy is quite misleading.

Your method makes much more sense.

Here’s there hint:
Use a while loop to check two things. First, check if the list has at least one element, using len(lst) . Second, check to see if the first element is odd using mod ( % ). If both of those are True, slice off the first element of the list using lst = lst[1:] .

#Write your function here

def delete_starting_evens(lst):

counter=0

for i in lst:

if i%2==0:

  counter+=1

  continue

lst=lst[counter:]

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

So, I’m having a really hard time grasping the code given for this section even though I’ve gone through it several times.

**1. Write a function called delete_starting_evens() that has a parameter named lst .

The function should remove elements from the front of lst until the front of the list is not even. The function should then return lst .

For example if lst started as [4, 8, 10, 11, 12, 15] , then delete_starting_evens(lst) should return [11, 12, 15] .

Make sure your function works even if every element in the list is even!

def delete_starting_evens(lst):
  for i in lst:
    if len(lst) % 2 != 0 and lst[:-1] % 2 != 0:
      return lst
 

So my logic is the first check if the list if it has an odd number of items then set another condition to parse through the elements to verify that they’re not even. In my mind, I thought an IF statement made more sense based on how the problem is worded so i could compmrehend it. Maybe my reasoning is off and my code is just making it more complicated.

Also I was thinking would using CONTINUE be an easier way to negate the even numbers in the list to get the same result?

Any help on this would be appreciate, I’ve been stuck on this all day and even a detailed explanation of the finished wasn’t too much help. :S

Any logic that contains a return better be well thought out. The above is not in that category. Go back to the question, and start over would be my advice.

Like I stated, I’ve been going through the solution all day which is why I’m asking for a possible alternative to the solution code given or a better explanation of the solution.

What is the return statement doing in the loop? What will the effect be? Don’t walk away from your unsolved code. Find out why it doesn’t work.

The return in a loop is a sign that sticks out. Were I a teacher I would say erase this and start over.


Now assuming you have resolved the return problem, what significance is there to the parity of the length in removing even numbers?

if len(lst) % 2 != 0

Ok, this helps and gives me a starting point. Thanks

1 Like