Подсчет того, сколько раз условие выполняется в Python

В 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 ответ
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 нет ничего плохого. В данном конкретном случае я не решила, что предпочитаю, пока или в следующий раз. Так что вы мог переключаться, но вам действительно не нужно.

    – не говори просто код

  • Хорошо, буду иметь это в виду, спасибо!

    – Кирела

  • 1

    Другими словами: многие новички в Python напишут или увидят while циклы и видят, как опытные программисты указывают на то, что они ужасны и что это должно быть сделано по-другому, и неправильно понимают это как «циклы пока всегда ужасно », а не означало« этот конкретный цикл while ужасен ». Подобно заблуждению,« чтобы быть питоническим, я должен написать этот код как одинарный »:-)

    – не говори просто код



Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *