Сравнение разности целых чисел в списке с заданным значением - PullRequest
0 голосов
/ 28 апреля 2018

Мой Python немного ржавый, и у меня действительно возникают проблемы с этим супер простым алгоритмом.

Я пытаюсь написать функцию, которая принимает два параметра (цель, значения), чтобы найти, какое число в значениях ближе всего к целевому числу; если есть связь, выберите меньшее число.

Вот мой прогресс, но я когда-либо выбирал только меньшее число, фактически не сравнивая разницу значений в списке по сравнению с относительным расстоянием до цели.

Так что, по сути, моя функция фактически не выполнила задачу вообще, потому что 47 на самом деле ближе к 46, чем 31; однако, если бы числа, содержащиеся в списке, были гипотетически 45 и 47, то они были бы одинаково далеки от моего целевого числа, и поэтому должно быть напечатано 45, а не 47.

Я бы предпочел ответы, которые используют простые циклы for / if / while, чтобы я мог по-настоящему практиковать свои навыки.

Другие более сложные ответы также приветствуются с подробным объяснением.

EDIT

Несколько действительно хороших ответов от вас, ребята, высоко ценится; Я тестирую их, пока мы говорим, и выберу наиболее подходящий для моего стиля и использую остальные в качестве ссылок, даже если у вас есть лучший однострочный ответ.

target = 46
values = [1, 22, 31, 47, 87, 99]

def closest_to_target(target, values):

    lower = []

    for number in values:
        if number < target:
            lower.append(number)

    if lower:
        lowest = sorted(lower, reverse=True)[0]
        return lowest

    else:
        return "Error handling array"


print closest_to_target(target, values)

Ответы [ 5 ]

0 голосов
/ 28 апреля 2018

Это можно сделать за один проход, отслеживая дельты. Если дельта равна предыдущей дельте, ближайший - это минимум предыдущего ближайшего и текущий. Если дельта меньше, обновите и дельту, и ближайшую из них текущими значениями. Все остальное, продолжай.

>>> target = 46
>>> values = [1, 22, 31, 47, 87, 99]
>>> closest = values[0]
>>> delta = abs(target - closest)
>>> for x in values:
...     d = abs(target - x)
...     if d == delta:
...         closest = min(closest, x)
...     elif d < delta:
...         delta = d
...         closest = x
...
>>> delta
1
>>> closest
47
>>>
0 голосов
/ 28 апреля 2018

Вы выбираете только те числа, которые меньше целевого, независимо от разницы. Для примера базового кода, который вы запросили, вы хотите рассмотреть модификацию линейного поиска, но просто отслеживать самую низкую разницу и значение, которое дает эту самую низкую разницу.

    def closest(target, values):
        smallest_difference = #a really large value to start
        closest_number = None
        for number in values:
            diff = abs(number - target)
            if diff == smallest_difference and number < closest_number:
               closest_number = number
            if diff < smallest_difference:
               closest_number = number
               smallest_difference = diff
        return closest_number

Преимущество этого метода в том, что вы не создаете дополнительные списки.

0 голосов
/ 28 апреля 2018

Вы можете использовать следующую функцию, которая создает кортежи значений и насколько близко значение к целевому значению. Сортируя по этому кортежу, вы не только получите элемент, ближайший к целевому значению, но в случае связей выберете наименьшее из связанных значений.

target = 46
values = [1, 22, 31, 47, 87, 99]

def closest_min(l, t):
  return sorted([(abs(t-i), l[e]) for e, i in enumerate(l)])[0][1]

print(closest_min(values, target))

Выход:

47

В случае галстука, правильно выберете низшее:

>>> closest_min([47, 45], 46)
45

Немного аккуратная версия с использованием min():

def closest_min(l, t):
      return min(l, key=lambda x:(abs(x-t), x))
0 голосов
/ 28 апреля 2018
def min_dist_index(target, values):
    values = sorted(values)
    dists = [abs(target-value) for value in values]
    index = dists.index(min(dists))
    return values[index]

target = 46
values = [1, 22, 31, 47, 87, 99]
print(min_dist_index(target, values))

Выход: 47

0 голосов
/ 28 апреля 2018

Вы можете создать список действительных чисел, которые затем могут быть обработаны с помощью так называемого понимания списка:

values[[abs(target-i) for i in values].index(min([abs(target-i) for i in values]))]

Здесь литерал списка [] используется для определения общего алгоритма, а не конкретных значений, каким должно быть содержимое списка. Каждый элемент в списке, i, получен из литерала списка, содержащего ваши значения, и проверяется по целевому номеру. Если они не соответствуют требованиям, они не содержатся в новом сгенерированном списке.

Реализация:

#!/usr/bin/env python

target = 46
values = [1, 22, 31, 47, 87, 99]


def closest_to_target(target, values):
    lower = values[[abs(46-i) for i in values].index(min([abs(46-i) for i in values]))]
    return lower

print(closest_to_target(target, values))

Который напечатает:

47

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...