В python я иногда пишу оператор while вроде
i = 0
while <condition that involves i>:
i += 1
Конечно, цель состоит в том, чтобы проверить, сколько раз выполняется условие. Мне было интересно, есть ли более простой питонический способ сделать это? что-то вроде i = while <condition that involves i>
, может с моржовым оператором?
Вот более конкретный пример:
def get_word_num_with_character_index(string: str, index: int) -> int:
"""
returns the number of the word containing a character, specified by an index
:param string: the string to analyze
:param index: the index of the character
:return: the number of the word containing the specified character
"""
split_string = string.split(" ")
i = 0
while len(" ".join(split_string[:i])) <= index:
i += 1
return i - 1
print(get_word_num_with_character_index("jean de la fontaine", 8))
# prints 2, the index of the word containing the 8th character
Как это упростить?
1 ответ
Ты мог замените ваш
i = 0
while len(" ".join(split_string[:i])) <= index:
i += 1
с одним лайнером, используя itertools.count
i = next(i for i in count() if len(" ".join(split_string[:i])) > index)
или более удобочитаемо распределено по двум физическим линиям (по-прежнему только одна логическая линия:
i = next(i for i in count()
if len(" ".join(split_string[:i])) > index)
У обоих есть преимущества. В while
решение меньше беспорядка, next
решение проясняет, что весь смысл фрагмента состоит в том, чтобы вычислить i
.
Если у вас уже есть функция для условия, хорошей альтернативой будет itertools.dropwhile
:
def condition(i):
return len(" ".join(split_string[:i])) <= index
i = next(dropwhile(condition, count()))
В качестве единственного лайнера, просто чтобы увидеть, насколько он длинный / уродливый в данном случае:
i = next(dropwhile(lambda i: len(" ".join(split_string[:i])) <= index, count()))
Так что я бы, вероятно, действительно использовал его, только если бы он у меня уже был как функция.
Большое спасибо!
itertools.count()
это то, что мне нужно прямо сейчас, но я продолжаюdropwhile()
в виду, это тоже очень актуально. Я всегда открыт для других идей. Но слово «мог» в вашем сообщении предполагает, что это плохая идея. Правда не очень понятно. То есть вы рекомендуете не использовать, а оставить «пока» как есть?— Кирела
Я имел в виду это, поскольку в цикле while нет ничего плохого. В данном конкретном случае я не решила, что предпочитаю, пока или в следующий раз. Так что вы мог переключаться, но вам действительно не нужно.
— не говори просто код
Хорошо, буду иметь это в виду, спасибо!
— Кирела
Другими словами: многие новички в Python напишут или увидят
while
циклы и видят, как опытные программисты указывают на то, что они ужасны и что это должно быть сделано по-другому, и неправильно понимают это как «циклы пока всегда ужасно », а не означало« этот конкретный цикл while ужасен ». Подобно заблуждению,« чтобы быть питоническим, я должен написать этот код как одинарный »:-)— не говори просто код