Reputation:
I am trying to understand the difference between looping over a list and looping over a "slice" copy of a list.
So, for example, in the following list, the element whose length is greater than 6 is appended to the beginning of the list:
words = ['cat', 'window', 'blahblah']
for word in words[:]:
if len(word) > 6:
words.insert(0, word)
print(words)
words = ['blahblah', 'cat', 'window', 'blahblah']
I, then, run the following to see why it is not the correct way of doing it, but my interpreter freezes and I have to exit. Why does this happen? I am simply appending something to the start of my list which is allowed since lists are mutable...
for word in words:
if len(word) > 6:
words.insert(0, word)
Could someone please help me understand why this last bit stops my program?
Upvotes: 2
Views: 1617
Reputation: 101
In case you want to see what exactly happens in the background of inserting into the list (words) vs slice copy (words[:]), you can change/tab the print to see the infinite loop, as the infinite loop cannot be seen in its original location in the script:
for w in words:
if len(w) > 6:
words.insert(0, w)
print(words) #prints after each insert, let you see the infinite loop
Upvotes: 0
Reputation: 2359
words[:]
means a new copy of the words
and length is fixed. So you are iterating over a fixed list.
But in the second situation, iterating over and extending the same list which makes it infinity.
words = ['cat', 'window', 'blahblah']
new_words = [_ for _ in words if len(_) > 6]
print(new_words)
Upvotes: 0
Reputation: 32464
The following loop
for word in words:
// do something
is roughly equivalent to the following one (when words
is a list and not another kind of iterable
):
i = 0
while i != len(words):
word = words[i]
// do something (assuming no 'continue' here)
i += 1
Therefore, when while looping you insert something into your list before the current position, then during the next iteration you end up handling the same element as for the previous iteration. In your case this results in an infinite loop.
Upvotes: 1
Reputation: 48067
When you are doing words[:]
, you are iterating over the copy of list, whereas with words
, you are iterating over the original copy of list.
In the case II
, your interpreter is freezing because when you are at the last index, the condition is satisfied and you insert the item at the beginning of the list. Now, there is one more index which is required to be iterated by the loop. Again, the condition satisfies and it keeps on going like this resulting in an infinite loop.
Where as that is not the case with words[:]
, as the list in which you are appending and the one on which you are iterating are different.
Upvotes: 1
Reputation: 27273
The list words
has three elements. The copy of words
also does. You iterate over the copy, insert something in words
if the current element is longer than 6 characters, and are done.
Now let's see what happens when you iterate over words
directly:
The first two iteration steps are fine, because the condition is False. But since len('blahblah') > 6
, you are now inserting 'blahblah'
at the beginning of the list. Now the list looks like this:
['blahblah', 'cat', 'window', 'blahblah']
You've just seen the third element, so now the loop continues and looks at the fourth element, but because you inserted something at the beginning of the list the rest of the list shifted and the new fourth element is 'blahblah'
again. blahblah
is still longer than 6 characters, you insert it again in the beginning and are stuck in an infinite loop:
['cat', 'window', 'blahblah']
^
['cat', 'window', 'blahblah']
^
['cat', 'window', 'blahblah']
^
['blahblah', 'cat', 'window', 'blahblah']
^
['blahblah', 'blahblah', 'cat', 'window', 'blahblah']
^
...
Upvotes: 5
Reputation: 400
In your first approach, you are performing a shallow copy of your list words
, iterating over it and appending long words to the list words
. So you iterate over a fixed list, and extend a different list.
With your last approach, the list words
grows with each iteration, so you are in an endless loop as you are looping over it and it keeps growing.
Upvotes: 1