Source code for smallest_two
"""This module contains four functions for finding the index of the
two smallest values in a list of numbers. The functions do not handle
the following extra cases:
* Lists with something other than numbers. The functions may work,
but uses the default ordering for these objects in Python.
* Lists with no values or a single value. The functions will fail
in this case.
The main code tests the performance of the functions using the time
module from Python. To be able to see the difference between the
different solutions, very large lists are required.
"""
import time
import random
[docs]def smallest_two1(l):
"""Algorithm for finding the index of the two smallest values
in the input list:
#. i0: smallest value, i1: second smallest value
#. initialize i0,i1 to 0, 1 in correct order
#. go through the indices of the rest of the list one by one
#. first check against the **second smallest**, and then the **smallest**,
switch values as appropriate
"""
if l[0] <= l[1]:
i0,i1 = 0,1
else:
i0,i1 = 1,0
for i in range(2,len(l)):
if l[i] <= l[i1]:
if l[i] <= l[i0]:
i1 = i0
i0 = i
else:
i1 = i
return (i0,i1)
[docs]def smallest_two2(l):
"""Algorithm for finding the index of the two smallest values
in the input list:
#. i0: smallest value, i1: second smallest value
#. initialize i0,i1 to 0, 1 in correct order
#. go through the indices of the rest of the list one by one
#. first check against the **smallest**, and then the **second smallest**,
switch values as appropriate
"""
if l[0] <= l[1]:
i0,i1 = 0,1
else:
i0,i1 = 1,0
for i in range(2,len(l)):
if l[i] <= l[i0]:
i1 = i0
i0 = i
elif l[i] <= l[i1]:
i1 = i
return (i0,i1)
[docs]def smallest_two3(l):
"""Algorithm for finding the index of the two smallest values
in the input list:
#. make a copy of the list and sort
#. find the two smallest values
#. find their indices using :func:list.index:.
#. if the two smallest values are the same, the index
of the second smallest must come after the index of the smallest.
"""
lcopy = l[:]
lcopy.sort()
v0 = lcopy[0]
v1 = lcopy[1]
i0 = l.index ( v0 )
if v0 != v1:
i1 = l.index ( v1 )
else:
i1 = l.index ( v1, i0+1)
return (i0, i1)
[docs]def smallest_two4(l):
"""Algorithm for finding the index of the two smallest values
in the input list:
#. find the min value, and then find the index of the min value
#. make a copy of the list, remove the smallest value (this will
remove the smallest value that is found first in the list hence
will match the index.)
#. find the next smallest value and its index.
"""
v0 = min(l)
i0 = l.index ( v0 )
lcopy = l[:]
lcopy.pop(i0)
v1 = min(lcopy)
if v0 != v1:
i1 = l.index ( v1 )
else:
i1 = l.index ( v1, i0+1 )
return (i0, i1)
if __name__ == "__main__":
##Test cases, two LONG lists in random order.
l = range(2000000)
random.shuffle(l)
l2 = range(2000000)
random.shuffle(l2)
print "Running version 1 of the smallest two function"
t0 = time.time()
(i0,i1) = smallest_two1(l)
(i0,i1) = smallest_two1(l2)
t1 = time.time()
print "It took %.3f seconds" %((t1 - t0)/2.0)
print "Running version 2 of the smallest two function"
t0 = time.time()
(i0,i1) = smallest_two2(l)
(i0,i1) = smallest_two2(l2)
t1 = time.time()
print "It took %.3f seconds" %((t1 - t0)/2.0)
print "Running version 3 of the smallest two function"
t0 = time.time()
(i0,i1) = smallest_two3(l)
(i0,i1) = smallest_two3(l2)
t1 = time.time()
print "It took %.3f seconds" %((t1 - t0)/2.0)
print "Running version 4 of the smallest two function"
t0 = time.time()
(i0,i1) = smallest_two4(l)
(i0,i1) = smallest_two4(l2)
t1 = time.time()
print "It took %.3f seconds" %((t1 - t0)/2.0)