Thank you @mtf - visual now helped to clear the tangled-up logic in my mind, thank you for your time and patience!
I have thought about this and now think I understand it.
Writing the following helped me to understand it.
Is the following a correct illustration of what happens?
lst = [4, 5, 6, 7, 8, 9]
for number in lst:
#the order of loops for this is:
#loop 1. -> 4 is popped
#loop 2. -> 5 moves to the slot vacated by the 4 (as lst is currently empty)
#loop 3. -> 5 is popped
#loop 4. -> 6 moves to the slot vacated by the 5
#loop 5. -> 6 is popped
#loop 6. -> 7 moves to the slot vacated by the 6
#you’re out of loops
#lst is now [7, 8, 9]
the loop doesn’t make 6 iterations:
lst = [4, 5, 6, 7, 8, 9] for number in lst: print "in loop:", lst lst.pop(0) print(lst)
it only make threes, the occupation of an empty slot happens before going to next iteration of the loop
But there are 6 items in the list. Does that not mean 6 loops in a for loop for that 6-itemed list?
no, there are 6 items in your list before you start the loop
you mean 6 iterations of the loop? The answer: no.
because you remove items from the list, the loop won’t have to make 6 iterations to reach the end of the list
I’ve did it another way without using pop(), here is my workaround:
#Write your function here def delete_starting_evens(lst): newlst =  for i in lst: if i%2==0: continue elif i%2!=0: newlst = lst[lst.index(i):] break return newlst #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, I was just wondering why my code doesn’t work:
for i in lst:
if i%2 == 0:
lst = lst[1:]
print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
My code seems to be printing [12,15], slicing out 11 as well.
When you do this, you shift the list to the left. However,
i is moving to the right, steadfastly.
How about my solution?
def delete_starting_evens(lst): empty =  for element in lst: if element % 2 != 0: index = lst.index(element) return lst[index:] return empty
Putting your trust in
object.index() is a mighty big play. Mind, we are only looking for the first occurrence, so in this one instance you could pull it off.
so is this wrong solution for this problem?
but i check every possible test cases, my code works fine!
“Wrong” did not come into question. It is a viable solution, not to be discounted. In fact it is literal in every sense. We do want the index of the first odd number. Perhaps I was a bit quick to jump on the don’t use
As that goes, I’m more trusting of the
enumerate function to give me the correct index of the value it currently sees. It never messes up on its position in the list.
When I used my for loop i tried to make a range list for list length. I was curious to know if this was the most efficient way to use the for loop in this case.
#Write your function here def delete_starting_evens(lst): new =  for i in range(len(lst))): if lst[i] % 2 == 1: new = lst[i:] break return new #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 have this code:
for num in lst:
if num % 2 > 0:
if len(lst) == 0:
if len(lst) == 1 and num % 2 == 0:
It works for this:
print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
But it’s not working for these:
print(delete_starting_evens([4, 8, 10, 6, 15, 24, 20, 1]))
print(delete_starting_evens([6, 8, 10, 23]))
On the fist of the two above the print out starts at 6, and the second at 10… I just can’t get my head to understand why the first print command actually prints the list starting at 11?
for is an iterator, and like all iterators has a
next() method behind the scenes. That method always points to the item or index following the one currently being visited. When we remove an element at the current position, the list shifts left, but not the next pointer. It stays where it is.
If we think about it, once this happens, we are never popping the item that we are actually looking at, but one to the left of that. I know, this is a poor explanation, but the bottom line is, don’t remove items from a list that being iterated with
for unless you have the mechanics down pat.
while since it does not have a
next() method. It just stays on the loop as long as the condition is met.
while len(lst) > 0: if lst % 2 == 0: lst.pop(0) else: break return lst
Play around with that and see what other forms you come up with.
Hey thanks for the explanation, it makes sense now, I did use the while loop and see how shorter it can be!
My solution was accepted by the console but I like to play more with my code to see if there’s a better way of doing things, only because of this I was able to see my solution didn’t really work for all the cases and so I started thinking what was going on.
>>> lst = [4, 5, 6, 7, 8, 9] >>> for index, number in enumerate(lst): print ("in loop:", lst) lst.pop(0) in loop: [4, 5, 6, 7, 8, 9] 4 in loop: [5, 6, 7, 8, 9] 5 in loop: [6, 7, 8, 9] 6 >>> lst [7, 8, 9] >>> index 2 >>>
There is no index so the loop terminates.
Rather than trying to make
for do something it can’t, just use
I appreciate that using .pop() in a for loop is not the way to go , I just wanted to understand why it creates the output it does.
I’ve understood everything in the Python3 course so far, but this one has been a bit difficult to get my head around to be honest!
I think I get it though.
The for loop goes through the cycle of iterating through indices , ,  and  then it is outside the list and can’t continue.
When the .pop() action takes place, the list becomes something new, but the for loop continues to cycle through , ,  and  as the list keeps changing.
list = [4, 5, 6, 7, 8, 9]
#ins= 0, 1, 2, 3, 4, 5
for loop cycle is for index 0 (4)
list is popped (4)
list = [5, 6, 7, 8, 9]
#ins= 0, 1, 2, 3, 4
for loop cycle is for index 1 (6)
list is popped (5)
list = [6, 7, 8, 9]
#ins= 0, 1, 2, 3
for loop cycle is for index 2 (8)
list is popped (6)
list = [7, 8, 9]
#ins= 0, 1, 2
for loop cycle can’t continue because there is no index 3
Thanks for helping me to understand this mtf and stetim94!
for x in lst:
i’m getting a return of [12,15]? I’m not sure why this isn’t returning the 11 as well.
Mutating a list in a for loop can be tricky and often messes things up.
Try iterating over a copy of the list so that it does not change when you alter the list itself.
for x in lst[:]
for x in lst.copy()
Now that list stays unchanged when you mutate