There are some comments I'd like to make about your codes before getting to your main question.
It looks like your algorithm expects a sorted list as an input. However, this is never documented and you can easily come up with a failing test case: I expect
[5, 16, 10, 15] to return
[16, 15], however I get
This can be fixed by working on a sorted list, or at the very least to clearly document that the method expects a sorted list
Test case n°8 returns
[10, 15] for input
[5, 10, 15]. However,
[5, 10] would be equally true. It should be documented what output will be favored in such cases of ties.
Don't use globals
Globals should be avoided, as they make the logic harder reason about and are prone to introducing bugs later on. They can also pollute the namespace if you
import * from your module.
The better way to do what you use globals for in this case is to pass these values as arguments:
def closest(List, deff=-1, num1=0, num2=0):
# do stuff
return closest(List[1:], deff, num1, num2)
You also use a global variable in your test suite (
allPassed). This one can easily be moved into the scope of
You should follow PEP8 for style conventions, including naming, unless you have a good reason to do otherwise (mostly conforming to existing conventions of the code base you are working on, which is not your case here).
The main difference here would be to rename variable and method names to
The algorithm you use is a fundamentally iterative one. You look at two consecutive elements of the list, compare their difference with the recorded minimum, then move one step further.
Using recursion on such an algorithm is a waste and brings no benefit. In fact, the recursive call is the last statement in the method (aka tail call recursion), and would be optimized to an iterative method by basically any optimizing compiler. However, Python being an interpreted language, it will not optimize and waste time and resource managing the call stack.
There are legitimate uses for recursive algorithms, but this is not one of them. If you really want to practice recursion, you should find something else to practice with.
Taking into account these remarks, this is my solution to the problem:
def closest(lst: list):
'''Find the two closest elements in a list of comparable items.
If more than one pair have the same difference, returns the smallest pair
>>>closest([1, 3, 4, 10])
>>>closest([1, 1, 1, 2, 2])
>>>closest([1, 9, 8, 3])
lst : list
a list of comparable values
The two closest elements in the input list
lst = sorted(lst)
v1 = lst
v2 = lst
min_diff = v2 - v1
for i in range(1, len(lst) - 1):
if lst[i+1] - lst[i] < min_diff:
v1 = lst[i]
v2 = lst[i+1]
min_diff = v2 - v1
return [v1, v2]