Why the else part is executed everytime the result is matched

The first problem:

def display(self): 

    if SearchString in per.fname:
        print per.fname, per.lname
    elif SearchString in per.lname:
        print per.fname, per.lname
    else:
        print "No String"

if statements do not form a group of alternatives themselves. To indicate that use the elif keyword, so the else part will be executed if none of the conditions were met.
In your first version, the first if was verified separately. After this there was a separate alternative: either print per.fname, per.lname if it’s true that SearchString in per.lname or print "No String", regardless of the result of the evaluation of the first if.

The second problem is here:

obj=[People("joe","foe"),People("lui","sui")]
for per in obj:
    per.display()

If you run the script with joe or foe as an argument in the first iteration it will print your expected result. However in the second iteration it won’t match anything in the second object and prints "No String".

A possible solution:

#!usr/bin/python
import sys

SearchString = sys.argv[1]

class People:
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

    def isMatching(self, matchString):
        return matchString in self.fname or matchString in self.lname

    def display(self): 
        print self.fname, self.lname

obj=[People("joe","foe"),People("lui","sui")]
anyMatched = False
for per in obj:
    if per.isMatching(SearchString):
        anyMatched = True
        per.display()

if not anyMatched:
    print "No String"

Note that the only thing I did is to make functions behave as their name says. If you stick to this simple rule it will save you a lot of trouble. Your original display function was doing a lot more then just “displaying” 🙂

Leave a Comment