0

I have the following binary search function:

def in_bisect(sorted_list, target):

    temp = sorted_list[:]
    low = 0 
    mid = (len(temp)-1) // 2 
    high = len(temp)-1 
    count = 0
    
    if target > temp[high] or target < temp[low]:
        return False
    
    while True:
        mid = len(temp) // 2 
        count += 1
        if target == temp[mid]:
            print("Target found in %d steps " % count)
            return True

        elif target > temp[mid]:  
            low = mid             
            temp = temp[low:]
        
        elif target < temp[mid]: 
            high = mid           
            temp = temp[:high]

    
    return False

It works fine when I look for an element on the given list of words. However, when I test a word that isn't on the list the loop goes to infinite!!!

I have tested it with a list of 113k+ alphabetically sorted words, and it is very efficient (or that what I'd like think at least) it finds the target in 17 steps maximum.

This is a test I did :

if __name__ == '__main__':
    fin = open('words.txt')
    a = []
    for line in fin:
        a.append(line.strip())
    print(in_bisect(a,'longsome'))

'longsome' is a word in words.txt file, if I change it to let's say 'blahblah' the loop goes for ever.

I would like it to return False immediately if there is no match. Also, any improvement suggestions along the way is appreciated, thanks.

10
  • Formatting help... Formatting sandbox Commented Aug 26, 2020 at 18:09
  • 2
    Have you tried using a debugger? Why not? Commented Aug 26, 2020 at 18:12
  • 2
    Why while True? Why not something like while len(temp) > 0? How do you expect to get out of the while loop if the word isn't actually present? Commented Aug 26, 2020 at 18:14
  • 1
    (you might want to change temp = temp[low:] to temp = temp[low + 1:], and do the same in reverse for high. After all, you know the element you just searched is wrong, so why include it?) Commented Aug 26, 2020 at 18:16
  • 1
    The 'while True' has no break.. Commented Aug 26, 2020 at 18:17

1 Answer 1

1

There was no way for the while loop to break, so until we run out of the range to search for, we go on, otherwise, we break. Also, low = mid + 1 was required as otherwise the list size won't reduce properly. Same for high.

def in_bisect(sorted_list, target):

    temp = sorted_list[:]
    low = 0 
    mid = (len(temp)-1) // 2 
    high = len(temp)-1 
    count = 0
    
    if target > temp[high] or target < temp[low]:
        return False
    
    while True:
        if len (temp) == 0:
            break
        mid = len(temp) // 2
        count += 1
        if target == temp[mid]:
            print("Target found in %d steps " % count)
            return True

        elif target > temp[mid]:  
            low = mid + 1             
            temp = temp[low:]
        
        elif target < temp[mid]: 
            high = mid - 1           
            temp = temp[:high + 1]

    
    return False
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks man, although @GreenCloakGuy did help with solving the problem in the comment above, by mentioning the list reduction issue. Thanks for both of you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.