Search code examples
pythonlistloopsinfinite-loop

Why is this an endless for loop?


I just went through the Looping Techniques Chapter of the Python docs tutorial and I have a question regarding this boy here: [:]

I learned that it takes the start and end index of a string, so:

text = "This is text"
text[:] # will return the whole text "This is text" and
tex[:4] # will return "This".

But when I saw this code here...

words = ['cat', 'dog', 'cowcowcow']
for w in words[:]:  # Loop over a slice copy of the entire list.
    if len(w) > 6:
        words.insert(0, w)
print words

Output:

['cowcowcow', 'cat', 'dog', 'cowcowcow']

...I didn't understand the meaning of [:] in the for loop. I would just write

for w in words:

but when I do so it's an endless while loop, why?


Solution

  • [:] means the range from the start to the beginning of the list - it's essentially copying the list (I generally advocate using list(...) instead for readability, it does the same job, and works for all iterables, not just sequences).

    The issue here is you modify the list while you loop, which then means there are more entries to loop over, so it becomes infinite.

    In general, modifying a list while iterating over it is a bad idea. Instead, consider a list comprehension to construct a new list.

    This code places all words with a length over six at the start of the list, in reverse order. So an alternative implementation would be:

    words = [w for w in reversed(words) if len(w) > 6] + words