#python
#python
Вопрос:
Вот тестовые примеры для кода:
-
- строка —
'Tim had been saying that he had been there'
- Поиск —
'had'
- ожидаемый результат — 4
- строка —
-
- строка —
'he got what he got and what he wanted'
- Поиск —
'he'
- ожидаемый результат — 2
- строка —
def return_distance(input, search):
words = input.split()
distance = None
indx = []
if not input or not search:
return None
else:
if words.count(search) >1:
indx = [ index for index, word in enumerate(words) if word == search]
distance = indx[1] - indx[0]
for i in range(len(indx)-1):
distance = min(distance, indx[i 1] - indx[i])-1
return distance
Я думаю, как оптимизировать код. Я признаю, что это плохо написано.
Комментарии:
1. Итак, код работает, и вы хотите его оптимизировать? Оптимизировать для удобства чтения, производительности …?
2. Спасибо за форматирование @ggorlen
3. да, больше похоже на pythonic
4. Перед оптимизацией я бы предпочел сделать это правильно . Вы получаете ошибку имени для
search_str
. И после исправления вы, например, терпите неудачу,return_distance('x o x x o x', 'x')
возвращая1
вместо0
.5. Спасибо, что указали на ошибку в коде. Исправлено @превосходный дождь
Ответ №1:
Как насчет
def min_distance_between_words(sentence, word):
idxes = [i for i, e in enumerate(sentence.split()) if e == word]
return min([y - x - 1 for x, y in zip(idxes, idxes[1:])])
Это разбивает входное предложение, составляет список каждого индекса, который соответствует целевому слову, затем выполняет итерацию по этому списку для вычисления различий между каждым индексом и возвращает минимальную разницу.
Поскольку поведение не определено, когда в предложении нет слова, оно выдает ошибку, но вы можете добавить проверку для этого и при желании вернуть значение по вашему выбору, используя min
‘s default
параметр:
def min_distance_between_words(sentence, word):
idxes = [i for i, e in enumerate(sentence.split()) if e == word]
return min([y - x - 1 for x, y in zip(idxes, idxes[1:])], default=None)
Кроме того, присвоение имени переменной input
перезаписывает встроенное и return_distance
является довольно неоднозначным именем для функции.
Добавление предварительного условия для параметров для, None
как это делается с if not input or not search:
, обычно не выполняется в Python (мы предполагаем, что вызывающий объект всегда будет передавать строку и придерживаться контракта функции).
Если вы хотите обобщить это дальше, переместите split()
обязанность в домен вызывающего объекта, который позволяет функции работать с произвольными итерациями:
def min_distance_between_occurrences(it, target):
idxes = [i for i, e in enumerate(it) if e == target]
return min([y - x - 1 for x, y in zip(idxes, idxes[1:])], default=None)
Вызов с:
min_distance_between_occurrences("a b c a".split(), "a")
min_distance_between_occurrences([(1, 2), (1, 3), (1, 2)], (1, 2))
Рефакторинг в сторону, как указано в комментариях, исходный код неверен. Проблемы включают:
search_str
не существует. Вы, вероятно, имели в видуsearch
.distance
иmin_dist
на самом деле не работают вместе. Выберите одно или другое и используйте его для всех минимальных вычислений.min(min_dist, indx[i 1] - indx[i])-1
вычитает 1 в неправильном месте, сбрасывая количество.
Вот потенциальное решение этих проблем:
def return_distance(input, search):
words = input.split()
distance = None
if words.count(search) > 1:
indx = [index for index, word in enumerate(words) if word == search]
distance = indx[1] - indx[0] - 1
# ^^^^
for i in range(len(indx) - 1):
distance = min(distance, indx[i 1] - indx[i] - 1)
# ^^^^
return distance
Комментарии:
1. Большое спасибо за красивое объяснение @ggorlen
Ответ №2:
Один из способов — использовать min
с пониманием списка на indx
min_dist = min([(indx[i 1] - indx[i]-1) for i in range(len(indx)-1) ])