1

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?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Johnny
  • 512
  • 2
  • 7
  • 18
  • 1
    http://stackoverflow.com/questions/6167238/what-does-in-python-mean http://stackoverflow.com/questions/4947762/python-why-use-list-when-list-refers-to-same-thing – Josh Lee Apr 22 '13 at 17:28
  • It’s not an endless while loop; if you wait long enough you’ll run out of memory and crash ;-) – Josh Lee Apr 22 '13 at 17:41

5 Answers5

7

[:] 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
Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
4

[:] creates a copy of the list. The slice takes all elements and returns a new list.

If you loop over the list itself, and keep adding elements to it, you end up with an endless loop. But if you loop over a copy instead, then the for loop won't see the original list being extended; the copy used for the loop doesn't see the extra element being added.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
3

Because when you use [:] it creates a copy of the original list, whereas when you omit it, you're looping over the same list, rather than a copy.

If you modify the list as you're looping over it, then you just keep adding to it and it keeps growing, so your loop continues.

If you modify the original while looping over a copy, however, then you'll reach the end of the copy and stop (because no new items were added to it).

Amber
  • 507,862
  • 82
  • 626
  • 550
2

In Python, you can't iterate over a list and remove elements from this list at the same time. words[:] returns a copy of words That way you can modify words while iterating through words[:].

aldeb
  • 6,588
  • 5
  • 25
  • 48
0
a=[1,2,3,4,5]
for i in a:
    if i==1 : 
         a.insert(0,i)
# you can see  endless loop . Because : 
i=1 =a[0]   #after first loop  a=[1,1,2,3,4,5]
# The second loop :
i=1 =a[1] # because   a=[1,1,2,3,4,5]
# after second loop  a=[1,1,1,2,3,4,5]
# So , endless loop , with result a=[1,1,1......,2,3,4,5].
#It very easy .
#If you user :
a=[1,2,3,4,5]
for i in a[:] :
 if i==1 : 
     a.insert(0,i)
#It same  : 
a_copy=a
for i in a:
    if i==1
      a_copy.insert(0,i)
linh nguyenvan
  • 111
  • 1
  • 5