2015-02-14 2 views
2

Я новичок в кодировании. Я ищу решение этой проблемы: Я должен написать функцию, которая хорошо берет строку текста со словами И номерами, разделенными пробелами, и из этой строки выводится True, если есть 3 слова подряд.Индекс Python за пределами рабочего диапазона

пример:

'123 a b c' == True 
'a 123 b c' == False 

То, что я пробовал:

def 3_in_a_row(words): 
    words = words.split(" ") 
    for i in range(len(words)): 
     return words[i].isalpha() and words[i+1].isalpha() and words[i+2].isalpha() 

Если я пытаюсь это я получаю ошибку list index out of range, потому что, когда я ближе к концу списка, не 2 слова после i для проверки.

Каков наилучший способ ограничить эту функцию, чтобы она остановилась, если нет 2 предметов после i для проверки? Что это лучший способ сделать это?

+0

спасибо. Я понимаю, где я сейчас ошибся. –

ответ

5

Вы можете ограничить диапазон:

range(len(words) - 2) 

поэтому он не будет производить индексы, которые вы не можете добавить 2 к.

Ваша петля возвращается слишком рано. Вы возвращаете результат тестирования только первые 3 слова. Например, ваш тест завершится неудачно для '123 a b c', так как только '123', 'a', 'b' испытывается на первой итерации. Alter ваш цикл в:

def three_in_a_row(words): 
    words = words.split(" ") 
    for i in range(len(words) - 2): 
     if words[i].isalpha() and words[i+1].isalpha() and words[i+2].isalpha(): 
      return True 
    return False 

Это теперь будет возвращаться рано, если вы нашли три слова подряд, и только после сканирования все слова это будет объявить поражение и вернуть False.

Некоторые другие советы:

  • Вы не можете создать идентификатор Python (например, имя функции) с цифрой. Первым персонажем есть письмо. Я переименовал вашу функцию выше в three_in_a_row().

  • Использование words.split() без аргумента. Это разбивает на произвольные пробелы и игнорирует пробелы в начале и в конце. Это означает, что раскол будет работать, даже если между чем-то есть 2 пробела или новая строка в конце или символ табуляции.

  • Вы можете использовать all() function, чтобы проверить вещи в цикле:

    if all(w.isalpha() for w in words[i:i + 3]): 
    

    является более компактным способом правописания же теста.

Demo с этими обновлениями:

>>> def three_in_a_row(words): 
...  words = words.split() 
...  for i in range(len(words) - 2): 
...   if all(w.isalpha() for w in words[i:i + 3]): 
...    return True 
...  return False 
... 
>>> three_in_a_row('123 a b c') 
True 
>>> three_in_a_row('a 123 b c') 
False 
>>> three_in_a_row('a b c 123') 
True 
1

Расширение @martijn's подробного ответа на использовании all, вот альтернатива одна линии;

>>> l = '.. a b .. e f .. g h i'.split() 
>>> pairs = [l[i:i + 3] for i in xrange(len(l))] 

>>> result = any([all(c.isalpha() for c in pair) for pair in pairs if len(pair) == 3]) 
Смежные вопросы