Megha_991
Megha_991

Reputation: 110

Else condition always works

There is a bug in my code which I'm not able to identify. This code should return True if the list contains [3,3].

But, if I write an else condition, it always shows False. If I skip the else condition, the code works fine.

def has_33(nums):
    for i in range(0,len(nums)-1):
        if nums[i]==3 and nums[i+1]==3:
            return True
        else:
            return False
    pass

The above code returns :

# Check
has_33([1, 3, 3]) . -- > False

# Check
has_33([1, 3, 1, 3]) --> False.

But, if I change the code to this :

def has_33(nums):
    for i in range(0,len(nums)-1):
        if nums[i]==3 and nums[i+1]==3:
            return True
    pass

The code works fine :

# Check
has_33([1, 3, 3]) --> True

# Check
has_33([1, 3, 1, 3]) -- > Returns nothing , False.

Why is this happening?

Upvotes: 2

Views: 220

Answers (4)

Piotrupio
Piotrupio

Reputation: 46

You can also make small adjustment in your function and decrease an indentation of "else" statement this way:

def has_33(nums):
    for i in range(0,len(nums)-1):
        if nums[i]==3 and nums[i+1]==3:
            return True
    else:
        return False
    pass

This is standard structure of "for" loop in Python - if your loop completes correctly without interruption (in your case - without finding two subsequent "3" on your list), it executes "else" statement.

Upvotes: 2

Hans Musgrave
Hans Musgrave

Reputation: 7141

The other answers explain the bug pretty well. I did want to point out two things though.

  1. A best practice in Python is to avoid iterating over a set of indices if possible, instead preferring to iterate over the object (e.g. for n in nums).
  2. There are library functions that make your life substantially easier.

Consider the following code using the any() and zip() built-in functions.

def has_33(nums):
    return any(x==y==3 for x, y in zip(nums, nums[1:]))

If you wanted, you could make this more general so that it might be applicable in other projects. The use of a default value preserves the original behavior.

def has_duplicate(nums, val=3):
    return any(x==y==val for x, y in zip(nums, nums[1:]))

Upvotes: 3

HaR
HaR

Reputation: 1067

It's because the else condition is satisfied first. You have a for loop which goes over all the numbers in your list [1,3,3], first it check's the first number which is 1 and then the second number which is 3;

if nums[i]==3 and nums[i+1]==3:

In this case nums[i] is 1 which means nums[i]==3 is not True , which means your code will go straight to the Else

And the solution to your problem is simple:

def has_33(nums):
    for i in range(len(nums)):
        if nums[i]==3 and nums[i+1]==3:return True
    return False

Upvotes: 3

Vikas Periyadath
Vikas Periyadath

Reputation: 3186

Try like this , The error occurring in your code because it will return and exit from code in the first loop itself. So you can give a flag and whenever the condition meets change the flag to true, then return the flag last:

def has_33(nums):
    flag = False
    for i in range(0,len(nums)-1):
        if nums[i]==3 and nums[i+1]==3:
            flag = True

    return flag

Upvotes: 2

Related Questions