3

Here is the function:

def is_sorted(L):
    """ (str) -> Bool

    Return True iff the L is sorted in nondecreasing order. Otherwise, return
    False.

    >>> is_sorted([1, 2, 3, 3])
    True
    >>> is_sorted([3, 2, 1, 3])
    False
    """
    if len(L) == 0:
        return False

    for i in range(len(L) - 1):
        if L[i] > L[i + 1]:
            return False

    return True

Then I executed it on a list with one character and it returns True. However, I expected to receive 'list index out of range error'. Could anyone explain why does it behave in such way?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Nicko
  • 51
  • 7

4 Answers4

3

range(a, b, s) is [a, a+s, a+2*s..., x] where x < b.

So range(0) -> range(0,0,1) generates an empty list. This means the inside of the for loop is skipped which returns True.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
RohithS98
  • 500
  • 2
  • 14
  • Thank you for the reply! Now it's clear. @RohithS98, what do you think about approach in this case? Is there any better solution? – Nicko Jul 03 '18 at 14:37
  • @Nicko This approach is good. There are some shorter(less lines) ways to do it like given [here](https://stackoverflow.com/questions/3755136/pythonic-way-to-check-if-a-list-is-sorted-or-not), but the basic concept is same, and have same complexity – RohithS98 Jul 03 '18 at 15:07
0

for i in range(n) means i shall iterate over the list [0,1,2....,n-1]. In your case range(0)=[] (an empty list) because there be no integer between 0 and 0. That's why this block of code is not getting executed:

for i in range(len(L) - 1): #empty list
    if L[i] > L[i + 1]: #this line is not getting executed
        return False

and this line is getting executed and it's returning True.

return True #this one is getting executed
Taohidul Islam
  • 5,246
  • 3
  • 26
  • 39
0

It returns True because it already can't go in the loop because the list is [], which is empty, so it just returns whats after it.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
0

Behind the scenes, the for statement calls iter() on the container object (here it is range). The function returns an iterator object that defines the method next() which accesses elements in the container one at a time. When there are no more elements, next() raises a StopIteration exception which tells the for loop to terminate.

In your snippet : range(0) implies loop will never run, instead stopIteration exception will be raised. Had it been range(0,1) you would get the expected answer. Hence, it jumps to the next statement and returns true.

You can read more about iterator protocol in python.

himank
  • 439
  • 3
  • 5