4

Just trying to do something like this. I want to keep appending to lst, and keep iterating over what was added.

lst = [secondLst]

for i in lst:

    *some code*

    lst.append(x)

And i would eventually reach x in the for loop.

Is this possible? Is there a better way?

3
  • You could use collections.deque, using pop and append on different sides. Commented Feb 4, 2018 at 2:16
  • Did it not work when you tried it? Commented Feb 4, 2018 at 2:30
  • @StefanPochmann No, it didnt. Im not really sure why not. Commented Feb 4, 2018 at 2:32

1 Answer 1

3

Yes, it works fine. Internally, Python maintains a list index, increments it by 1 on each iteration, and checks it anew against the then-current length of the list each time. The list length is not captured at the very start of the loop. So, for example:

>>> L = [10, 20, 30]
>>> for i, v in enumerate(L):
...     print(v)
...     if i < 3:
...         L.append(i)

10
20
30
0
1
2

It may be clearer to do it more explicitly, though. For example:

>>> import itertools
>>> L = [10, 20, 30]
>>> extras = []
>>> for i, v in enumerate(itertools.chain(L, extras)):
...     print(v)
...     if i < 3:
...         extras.append(i)

You can read the docs:

Note: There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, i.e. lists). An internal counter is used to keep track of which item is used next, and this is incremented on each iteration. When this counter has reached the length of the sequence the loop terminates. This means that if the suite deletes the current (or a previous) item from the sequence, the next item will be skipped (since it gets the index of the current item which has already been treated). Likewise, if the suite inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop.

Sign up to request clarification or add additional context in comments.

9 Comments

This is incorrect. enumerate makes a copy of the list and you will not be iterating over the addition too.
@NoticeMeSenpai, not so. Run the code. It works fine. enumerate() copies nothing. If you're the one who down-voted this answer, you should retract it ;-)
@StefanPochmann, see the edit just now for a doc reference. It's explicitly pointing out what can go wrong, but you can also infer from it the behavior I already described.
I'm not sure if this is a good approach. Based on OP's original code, it seems they want to add directly to the list being iterated. In this case it'll easily create an infinite loop as the index will never reach the end. I think it's important to point out the use of your if i < 3: just so OP doesn't run into an infinite loop.
@TimPeters Hmm, that does sound rather convincing. A while ago I tried hard to find it documented properly but failed. Martijn Pieters also seemed to not be aware of that note when I asked him recently. Not sure I haven't seen this note before or did but still didn't trust it fully. It doesn't say when exactly the counter-vs-length check is done and I thought it could be done right after taking an element, before giving it to the loop body, so an append when you're already at the ...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.