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.
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