Python Forum

Full Version: Understand for range concept
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyoine,

I had a doubt about for range in Python when I also use string length or array, for example:
def name(s): 

    l = s.split() 
  
    for i in range(len(l)-1): 
        s = l[i] 
        print(s)
                     
s ="mohandas karamchand gandhi" 
print(name(s)) 
output : 
mohandas
karamchand
None
def name(s): 

    l = s.split() 
  
    for i in range(len(l)+1): 
        s = l[i] 
        print(s)
                     
s ="mohandas karamchand gandhi" 
print(name(s)) 
output : 
mohandas
karamchand
gandhi
Why if I change the operator in Len (s) [ + / - ] 1, does it give me different results?
Regards,
RavCoder
Don't use this style. In Python it is done like:

>>> s ="mohandas karamchand gandhi" 
>>> for word in s.split():
...     print(word)
... 
mohandas
karamchand
gandhi
As for range you can simply observe by printing out:

>>> s = 'abc'
>>> len(s)
3
>>> first = len(s) + 1
>>> first
4
>>> second = len(s) - 1
>>> second
2
>>> list(range(first))
[0, 1, 2, 3]
>>> list(range(second))
[0, 1]
  
    for i in range(len(l)-1): 
        s = l[i] 
        print(s)
                     
s ="mohandas karamchand gandhi" 
You are making a list of the elements after splitting the string "mohandas karamchand gandhi". So the positions and values of that list are:
l[0] = 'mohandas'
l[1] = 'karamchand'
l[2] = 'gandhi'

Therefore, the len(l) = 3 because the list has 3 elements: ['mohandas', 'karamchand', 'gandhi']. Consequently, len(l)-1 = 3 -1 = 2 and as a result, range(len(l)-1) = range(2). The function range starts at '0' (if you don't write anything else) and ends with a number a unit less than the limit (the limit number is not used). So range(2) means numbers 0 and 1.

So you then make the program print the elements of that list and positions:
l[0] = 'mohandas'
l[1] = 'karamchand'
and my understanding is that because you asked to print the whole string with print(s), but had previously limited the list to be printed with positions '0' and '1', the last element of the list is printed as 'None'.

    for i in range(len(l)+1): 
        s = l[i] 
        print(s)
                    
s ="mohandas karamchand gandhi" 

In a similar way, len(l)+1 = 3 + 1 = 4 and as a result, range(len(l)+1) = range(4). The function range starts at '0' (if you don't write anything else) and ends with a number a unit less than the limit (the limit number is not used). So range(4) means numbers 0, 1, 2 and 3.

So you then make the program print the elements of that list and positions:
l[0] = 'mohandas'
l[1] = 'karamchand'
l[2] = 'gandhi'
l[3] produces an IndexError: list index out of range as there are no elements in the list in position [3].

I hope it helps.

All the best,
Whenever you see range(len(...)) there is probably a better way to do it.
See Ned Batchelder's talk - Loop like a native
I agree with Perfringo and Jefsummers that there are better ways to do what you wanted with your code.

Nevertheless, I tried to explain the concept of the function range() and how it works, so I didn't pay much attention to the rest of the code. Later on, I wondered myself why that 'None' appeared, and then I noticed that you put at the end of your code the line:

print(name(s))
so you are asking to print a function (name(s), defined by yourself, that has already a print() function in it:

print(s)
so there is no need to write that last line of your program as print(name(s)). You just need to call the function for that string with:

name(s)
With that modification, your program:

def name(s): 
 
    l = s.split() 
   
    for i in range(len(l)-1): 
        s = l[i] 
        print(s)
                      
s ="mohandas karamchand gandhi" 
name(s)
produces the following output:
Output:
mohandas karamchand
and your other version of your program with my modification:
def name(s): 
 
    l = s.split() 
   
    for i in range(len(l)+1): 
        s = l[i] 
        print(s)
                      
s ="mohandas karamchand gandhi" 
name(s)
produces the following output, with an error message:
Output:
mohandas karamchand gandhi
Error:
Traceback (most recent call last): File "C:/Users/User1/AppData/Local/Programs/Python/Python37/aaa1.py", line 10, in <module> name(s) File "C:/Users/User1/AppData/Local/Programs/Python/Python37/aaa1.py", line 6, in name s = l[i] IndexError: list index out of range
The program following your code to produce the desired output (but keep in mind that there are better ways to do it) is:

def name(s): 
 
    l = s.split() 
   
    for i in range(len(l)): 
        s = l[i] 
        print(s)
                      
s ="mohandas karamchand gandhi" 
name(s)
and produces the following output:
Output:
mohandas karamchand gandhi
All the best,