小能豆

Python:退出for循环?

py

我在 SO 上做了一些研究,知道有很多类似的问题被问到,但我无法得到答案。无论如何,我正在尝试构建一个库来使用“Cesar 数”技术“加密”字符串,这意味着我必须取出字符串并将每个字母替换为字母表中 X 位置的另一个字母(我希望这是有意义的)。这是我的代码:

from string import ascii_lowercase, ascii_uppercase

def creer_encodeur_cesar(distance):

    retour = lambda x: encodeur_cesar(x, distance)
    return retour

def encodeur_cesar(string, distance):
    tabLowerCase = list(ascii_lowercase)
    tabUpperCase = list(ascii_uppercase)
    tabString = list(string)

    l_encodedStr = []

    for char in tabString:
        position = 0
        if char == " ":
            pass
        elif char.isupper():
            #do something

        elif char.islower():
            for ctl in range(0, len(tabLowerCase)):
                position = ctl
                if char == tabLowerCase[ctl]:
                    if (ctl + distance) > 26:
                        position = ctl + distance - 25
                    char = tabLowerCase[position + distance]
                    l_encodedStr.append(char)
                    #How to break out of here??


        encodedStr = str(l_encodedStr)

        return encodedStr

encodeur5 = creer_encodeur_cesar(5)
print(encodeur5("lionel"))

因此,在我的第二个 elif 语句中,我希望在成功找到并加密字符后立即中断,而不是循环遍历整个字母表。我尝试使用,break但它跳出了主 for 循环。这不是我想要的。我看到我可以使用try exceptand,raise但我不知道该怎么做,这是一个好主意吗?

最好的方法是什么? 在这种情况下,有哪些好的做法?


阅读 11

收藏
2024-11-19

共1个答案

小能豆

你的问题是关于如何在嵌套循环中找到特定条件后退出内层循环,同时保持主循环的继续运行。在你的情况下,你不需要嵌套循环,因为你已经有字母表的索引,可以直接用索引计算出加密后的字符,而不需要循环遍历整个字母表。

以下是改进的代码:

改进后的解决方案

from string import ascii_lowercase, ascii_uppercase

def creer_encodeur_cesar(distance):
    # 返回一个闭包函数
    return lambda x: encodeur_cesar(x, distance)

def encodeur_cesar(string, distance):
    tabLowerCase = ascii_lowercase
    tabUpperCase = ascii_uppercase
    l_encodedStr = []

    for char in string:
        if char.islower():
            # 找到字符在小写字母表中的位置并加密
            new_char = tabLowerCase[(tabLowerCase.index(char) + distance) % 26]
            l_encodedStr.append(new_char)
        elif char.isupper():
            # 找到字符在大写字母表中的位置并加密
            new_char = tabUpperCase[(tabUpperCase.index(char) + distance) % 26]
            l_encodedStr.append(new_char)
        else:
            # 非字母字符保持不变
            l_encodedStr.append(char)

    # 将加密后的字符列表转换为字符串
    return ''.join(l_encodedStr)

# 使用加密器
encodeur5 = creer_encodeur_cesar(5)
print(encodeur5("lionel"))  # 输出:"qntsjq"

改进点解释

  1. 避免嵌套循环
  2. 在原始代码中,使用了嵌套循环(for ctl in range(...))去查找字母的位置。这是多余的,因为可以直接用 .index(char) 来获取字母的位置。
  3. 并且直接用 (index + distance) % 26 实现了字母表的环绕效果(处理超出字母表末尾的情况)。

  4. 字符分类处理

  5. 根据字符是否为大写、小写或非字母分别处理,使代码逻辑更加清晰。
  6. 使用 str.index() 来获取字符的位置,无需手动遍历字母表。

  7. 保持其他字符不变

  8. 任何非字母字符(如空格、标点符号等)原样添加到结果中。

关于你的原始问题

如果你坚持要在嵌套循环中使用 break 退出,可以这样做:

for ctl in range(len(tabLowerCase)):
    if char == tabLowerCase[ctl]:
        new_pos = (ctl + distance) % 26
        char = tabLowerCase[new_pos]
        l_encodedStr.append(char)
        break  # 退出当前循环

这种方式虽然可行,但效率较低,因为你不需要用循环查找字符的位置。


总结

最佳实践是避免不必要的嵌套循环,尽可能利用 Python 提供的内置方法(如 str.index())和简洁的数学计算来处理问题。这种方式不仅简化了代码,还提高了运行效率。

2024-11-19