Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python "for in" loop to print the last item in the list

Lately I learned about lists and for loops, as well as the command .pop() that indicates and removes the last item in a list.

So I tried to write a code to remove the last items in a list one by one, until it remains with only one item.

The code is:

list_A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

for i in list_A:
    print(list_A.pop())
    if 'c' not in list_A:
        break

print("job done.")

The output of python 3.6 gives me this:

/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6
j
i
h
g
f
job done.

As you can see, it actually worked, but for a half of it?

I was expecting:

j
i
h
g
f
e
d
c
job done

I mean, I will be more comfortable if it returns some error, that means the code is not right. But why did it work, but not a full way through?

like image 512
jxie0755 Avatar asked Sep 07 '17 01:09

jxie0755


Video Answer


2 Answers

You are mutating the list whilst iterating over it.

You can use a while loop to do this:

list_A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

while 'c' in list_A:
    print(list_A.pop())

print('job done')

Output:

j
i
h
g
f
e
d
c
job done

A more efficient way would be to determine the index of the first instance of the sentinel character, and remove it and the rest of the list (although the characters are not printed as they are removed):

try:
    pos = list_A.index('c')
    list_A[:] = list_A[:pos]
    # del list_A[pos:]           # more efficient alternative suggested by @ShadowRanger
except ValueError as e:
    pass
like image 77
mhawke Avatar answered Oct 21 '22 17:10

mhawke


When using a for..in loop in Python, you are not supposed to modify the list.

What happened here is the following:

  • The loop goes from the first item to the last, so it starts at a
  • pop() removes the last list entry, so in that first loop iteration you get rid of the last letter j and print it
  • This all continues for the next 5 letters. You iterate over them from the left, but remove the last one on the right at at the same time
  • When meeting e you remove and print f from the list
  • After that the list contains the letters a to e and since you just iterated over e the loop's job is done

It's really hard to say what you wanted to do here, since it's more of playing around rather than getting something done. I would suggest to use a while loop though, whenever you intend to edit the list from within the loop. Your example with proper semantics could look like this:

while list_A:
    print(list_A.pop())
    if "c" not in list_A:
        break

This loop goes for as long as there is items in the list and only stops once there is no c in the list anymore.

like image 42
Hubert Grzeskowiak Avatar answered Oct 21 '22 17:10

Hubert Grzeskowiak