input:
ls = ['hi', 'bye', 'cya', 'hello', 'nope']
ls_popped = []
i = 0
while i < 3:
ls_popped.append(ls.pop(i))
i = 1
print(ls)
print(ls_popped)
output:
['bye', 'hello']
['hi', 'bye', 'nope']
expected output:
['hello', 'nope']
['hi', 'bye', 'cya']
i believe the pop function pops and returns the element at index i, so it should pop from i = 0 to 2 and return these elements to the new list. im not sure why this is not working as expected.
CodePudding user response:
If you want to mutate a list while iterating through it, you should iterate in reverse.
i = len(ls)
while i >= len(ls)-2:
ls_popped.append(ls.pop(i))
i -= 1
Otherwise, you change the indices of the next items and everything becomes out of order. Going reverse ensures that the indices to come, stay to say throughout the iteration.
CodePudding user response:
Let's trace it through. At the beginning of your program, we have
ls = ['hi', 'bye', 'cya', 'hello', 'nope']
ls_popped = []
i = 0
Now we run the loop once. We pop the element at position 0 and append it to ls_popped
.
ls = ['bye', 'cya', 'hello', 'nope']
ls_popped = ['hi']
i = 1
Great! Now the loop variable is 1
. So we pop the thing at position 1. Note that that's not bye
: bye
is at 0 now, while cya
is at 1.
ls = ['bye', 'hello', 'nope']
ls_popped = ['hi', 'cya']
i = 2
Now i
is 2, so we're looking at position 2, which contains nope
.
ls = ['bye', 'hello']
ls_popped = ['hi', 'cya', 'nope']
i = 3
Now i
is 3 so the loop exits and we move on, printing the result
CodePudding user response:
It helps to see your list visually:
'hi', 'bye', 'cya', 'hello', 'nope'
-----------------------------------
0 1 2 3 4
We start with the while
loop at 0
, and extract the first element and put in ls_popped
. When you extract the first element the remaining elements in ls
shift, so visually it will look like:
'bye', 'cya', 'hello', 'nope'
-----------------------------
0 1 2 3
Now i
is increased to 1
and so you now extract cya
and store it in the ls_popped
.