Python索引超出范围

时间:2015-02-14 07:45:41

标签: python for-loop

我是编码的初学者。我正在寻找这个问题的解决方案: 我应该编写一个函数,它可以使用带有单词和数字的文本字符串,用空格分隔,如果连续有3个单词,则输出该字符串输出True。

示例:

'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错误,因为当我接近列表末尾时,i之后没有2个字要检查。

限制此功能的最佳方法是什么,以便在i检查后没有2个项目时停止?有什么更好的方法呢?

2 个答案:

答案 0 :(得分:5)

您可以限制范围:

range(len(words) - 2)

所以它不会产生你不能添加2的索引。

然而,你的循环太早了。您将返回仅测试前3个单词的结果。例如,'123 a b c'的测试将失败,因为在第一次迭代中仅测试'123', 'a', 'b'。改变你的循环:

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]):
    

    是拼写相同测试的更紧凑的方式。

使用这些更新进行演示:

>>> 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 :(得分: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])