简体   繁体   English

为什么会出现 IndexError 以及如何使这段代码更简洁

[英]Why am I presented with an IndexError and what ways can I make this code more succinct

so I'm struggling to complete a coding challenge in CodeWars, and I received an IndexError on CodeWars.所以我正在努力完成 CodeWars 中的编码挑战,并且在 CodeWars 上收到了 IndexError。 When I run the code on PyCharm, the output is fine.当我在 PyCharm 上运行代码时,output 很好。

Coding Prompt编码提示

def alphabet_position(sentence):
    alphabet_cap = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    alphabet_low = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

    sentence_list = list(sentence)

    # remove any non-letters from sentence
    i = 0
    while i < len(sentence_list):
        if sentence_list[i].isalpha() == False:
            sentence_list.remove(sentence_list[i])
        i += 1

# I had to create a specific remove(" ") because for some reason the "'" would be turned into a " " instead of being removed?
    i = 0
    while i < len(sentence_list):
        if sentence_list[i] == " ":
            sentence_list.remove(" ")
        i += 1

    # finding position of alphabet
    alpha_index = []
    k = 0
    j = 0
    while k < len(sentence_list):
        if sentence_list[k] == alphabet_low[j] or sentence_list[k] == alphabet_cap[j]:
            alpha_index.append(str((alphabet_low.index(alphabet_low[j])) + 1))
            j = 0
            k += 1
        else:
            j += 1

    sentence_index = " ".join(alpha_index)

    return sentence_index

Error message错误信息

Sample Tests:样品测试:

from random import randint
test.assert_equals(alphabet_position("The sunset sets at twelve o' clock."), "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11")
test.assert_equals(alphabet_position("The narwhal bacons at midnight."), "20 8 5 14 1 18 23 8 1 12 2 1 3 15 14 19 1 20 13 9 4 14 9 7 8 20")

number_test = ""
for item in range(10):
    number_test += str(randint(1, 9))
test.assert_equals(alphabet_position(number_test), "")```

Any help would be appreciated!

I can't really replicate the IndexError , but I can help you out with the compactness of your code.我无法真正复制IndexError ,但我可以帮助您解决代码的紧凑性。 The quickest way I can think of for getting the job done is something like this:我能想到的完成工作的最快方法是这样的:

import re # for the regular expression

def alphabet_position(sentence):

    # regular expression to filter out everything that is not a letter
    regex = re.compile('[^a-zA-Z]')

    # removing everything that doesn't match the regex
    sentence = regex.sub('', sentence)

    alpha_index = []
    for char in sentence.upper():
        # ord() returns the ASCII code,
        # we subtract by 64 to get the alphabetical index,
        # then we convert the integer to string
        # because the final result needs to be a string

        alpha_index.append(str(ord(char) - 64))
    
    return " ".join(alpha_index)

An explanation of what is going on:对正在发生的事情的解释:

  1. We don't need to store into two lists all the possible characters we need.我们不需要将我们需要的所有可能的字符存储到两个列表中。 We can just use a regular expression to remove everything that is not an alphabetical character: [^a-zA-Z] .我们可以使用正则表达式来删除所有字母字符: [^a-zA-Z]
  2. There's no need to iterate 3 times over the string: the regex takes care of the filtering, then we can use a single iteration over every character to find out their index in the alphabet.不需要对字符串进行 3 次迭代:正则表达式负责过滤,然后我们可以对每个字符使用单次迭代来找出它们在字母表中的索引。 To do this, first we convert everything to uppercase with sentence.upper() , then we check the ASCII value of the current character and we subtract 64. This is done because the ASCII values follow the alphabetical order, and the first character, A, has value 65. Take a look at the table .为此,首先我们使用sentence.upper()将所有内容转换为大写,然后检查当前字符的 ASCII 值并减去 64。这样做是因为 ASCII 值遵循字母顺序,而第一个字符 A , 值为 65。看一下表格

If you don't know how to use regular expressions, another way to solve the problem is如果你不知道如何使用正则表达式,另一种解决问题的方法是

def alphabet_position(sentence):
    alpha_index = []
    for char in sentence.upper():
        if char.isalpha() and 65 <= ord(char) <= 90:    # 65: A ascii value, 90: Z ascii value
            alpha_index.append(str(ord(char) - 64))
    
    return " ".join(alpha_index)

One drawback of this approach, as Luke Woodward pointed out in his comment to your question, is that if we have non-standard character, as accented letters, they get filtered out.正如卢克伍德沃德在对您的问题的评论中指出的那样,这种方法的一个缺点是,如果我们有非标准字符,例如重音字母,它们就会被过滤掉。 If that is the case, you might want to expand either the regex or the ASCII filtering.如果是这种情况,您可能需要扩展regex或 ASCII 过滤。

Code with inline comments:带有内联注释的代码:

alphabet_low = "abcdefghijklmnopqrstuvwxyz"

def alphabet_position(sentence):
    result = []  # initialize result
    for char in sentence.lower():  # iterate over lowercase string
        if char in alphabet_low:  # is character in alphabet?
            position = alphabet_low.find(char) + 1
            result.append(str(position))
    return " ".join(result)

sentence = "The sunset sets at twelve o' clock."
print(sentence)
print(alphabet_position(sentence))

Output: Output:

The sunset sets at twelve o' clock.
20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM