问题
I am given a list of integers/floats and I need to find the two numbers closest together. How would I do that using only nested for loops?
回答1:
For each element, you have to compare the distance of it to each of the other elements with your previous "closest" value - any time this comparison yields smaller values, you remember that pair as the "two closest" ones.
So, it is straightforward:
def find_two_closest(numbers):
# most distant points:
delta = max(numbers), min(numbers)
for i, element in enumerate(numbers):
for j, sec_element in enumerate(numbers):
if i == j:
continue
if abs(sec_element - element) < abs(delta[0] - delta[1]):
delta = sec_element, element
return delta
回答2:
If the points are one dimensional (as in your input is just a list of numbers like [1, 4, 6, 2]
), then you can easily do it in O(n log n) time by sorting them and finding the ones with the smallest difference:
def smallest_difference(points):
sorted_points = sorted(points)
return min(abs(prev - cur) for cur, prev in zip(sorted_points, sorted_points[1:]))
If you want to get the closest points instead of the distance between the closest points, use the key=
parameter of the min
function:
import operator
def smallest_difference(points):
sorted_points = sorted(points)
return min(zip(sorted_points, sorted_points[1:]), key=lambda x: abs(x[1] - x[0]))
If the points are two dimensional (as in your input is a list of 2 element tuples like [(1, 2), (3, 4), (5, 2)]
) then the Wikipedia article for this problem https://en.wikipedia.org/wiki/Closest_pair_of_points_problem describes how to extend this to two dimensions.
回答3:
Checking each two points is not necessary and it's slow O(n^2).
I suggest to:
1) Sort the input.
2) Compare each two following values and choose smallest.
Timing will be much better O(n*log n) assuming that you use efficient sorting algorithm.
Code example:
input = [0, 65, 10, 100, 1231] #whatever you put here; it might be tuple, list, set, range, etc.
def find_closest(input):
sorted_input = sorted(input)
best = (sorted_input[-2], sorted_input[-1], sorted_input[-1] - sorted_input[-2])
for i, val in enumerate(sorted_input[:-1]):
d = sorted_input[i+1]-val
if d < best[2]:
best = (val, sorted_input[i+1], d)
return best
Function returns both values and distance between them.
回答4:
Here is a quick fix only with nested for
loops and if
conditions; and nothing else.
Needless to say that this is the most inefficient way of doing this, but I assume there is reason for it (learning something?). If that's the case, you should spend some time trying to learn the process.
my_list = [1, 3, 9, 14, 12, 20, 22]
c = list()
for value_1 in my_list:
for value_2 in my_list:
if value_1 != value_2 and value_2-value_1>0:
c.append({
'val_1': value_1,
'val_2': value_2,
'delta':value_2 - value_1
})
minimum = c[0]['delta']
for item in c:
num = item['delta']
if minimum > num:
minimum = num
print(str.join('\n', [str(item) for item in c if item['delta'] == minimum]))
which returns:
{'val_1': 1, 'val_2': 3, 'subtraction': 2}
{'val_1': 12, 'val_2': 14, 'subtraction': 2}
{'val_1': 20, 'val_2': 22, 'subtraction': 2}
来源:https://stackoverflow.com/questions/36845202/get-the-two-closest-points-from-a-list-of-points