for loop and slice

for statement iterates on any discrete sequence of items – as in Java. The syntax is simple:

for <variable> in <sequence>:
    <statement>

Eg.:
words = ['this', 'that', 'another']
for w in words:
     print(w, len(w))



Side-note here –
      for w in words[:]: print(w)
   has the same effect as
     print(words)


You can update a list within the for loop – unlike Java.

for w in words:
     if len(w) > 6:
          words.remove(w)


But, better use a slice to end up with the expected effect in some cases. For instance, the following is an infinite for-loop:

for w in words:
     if len(w) > 6:
          print(w,' here is one')
          words.insert(0, w)
     else: print(w,' nope')

This is because, it keeps iterating on the current list – the list that keeps getting updated to grow bigger in matching cases.


Slice is like a view of, or an iterator on the original list. The loop is updating the list as coded, but iterating on this view – not the updated list:

for w in words[:]: # line-K
     if len(w) > 6:
          print(w,' here is one')
          words.insert(0, w)
     else: print(w,' nope')

The notation [:] defined a slice – this iterator/view. I’ll go through this notation later in detail, but quickly now – the format is

[<begin>: <end>:<increment>]


It tells at which list member the iteration starts (inclusive), ends (exclusive), and by how many increments. The increment here is optional – has default value of 1 when omitted. <begin>, <end> and <increment> can take negative values to indicate iteration in the reverse order, and/or with respect to the end, not the beginning of the list. Slice also seems to be the notation/concept used on such other discrete, one-dimensional items like arrays. I’ll go through these with the entire details another time.

So, the following for statement has the exact same effect as does ‘line-K’ above.

for w in words[0:words.__len__():1]:
     if len(w) > 6:
          print(w,' here is one')
          words.insert(0, w)
       else: print(w,' nope')


The following for statements all have the same effect in this case:
for w in words[0:words.__len__():1]:
for w in words[0:words.__len__()]: # default increment
for w in words[0:99]: # any value greater than the size of the list
for w in words[slice(0, words.__len__(), 1)]: # ..or, just downright use slice() function
for w in words[slice(0, words.__len__())]: # ..or, just downright use slice() function
for w in words[::]: # all default values – the entire list. 
                                # can’t do this on slice() -- has to take the 2 mandatory arguments.
for w in words[:]: # just what it takes to get a slice of the list.


Note here that, the slice range seems to be assigned once – just before getting into the for-loop, and doesn’t change with the changing value of the variable it takes its value from. So by this – words.__len__() for the end of slice doesn’t cause any change on the values being iterated on just because the length of words has changed during the iteration. Also try defining a variable and taking these values from this variable to see the same thing – something like

ii = 3;
for w in words[0:ii:1]:
     if len(w) > 6:
            print(w,' here is one')
              words.insert(0, w)
       else: print(w,' nope'); ii=1

Comments

Popular posts from this blog

Python - what for?

Intro

..And the very first step