HOWTO · Python

检查字符串是否是 Python 中的回文

本文介绍六种在 Python 中检查字符串是否为回文的方法:字符串切片、reversed()、循环、递归、双端队列,以及忽略大小写和非字母数字字符的文本规范化。切片可直接用于字符串,并非列表方法。

本页内容

回文正读和反读都相同,例如 level。基本检查会逐个比较输入中的字符。如果要忽略大小写、空格或标点,请先规范化文本。

使用切片检查 Python 字符串是否为回文

字符串切片会创建一个反转后的副本。[::-1] 切片会从字符串的最后一个字符遍历到第一个字符,因此将它与原字符串比较,就能简洁地进行原样检查。把 level 替换为要检查的值。

word = "level"
print("Palindrome" if word == word[::-1] else "Not Palindrome")

切片可以直接用于字符串;它不是列表方法。这种比较区分大小写,并将空格和标点视为普通字符。该操作需要线性时间,并会创建一个反转后的字符串。

使用 reversed() 检查 Python 字符串是否为回文

内置函数 reversed() 会返回一个按相反顺序遍历字符的迭代器。先用 join() 将迭代器转换为字符串,再与原字符串比较。

word = "level"
reverse = "".join(reversed(word))
print(word == reverse)

reversed() 本身不会返回字符串。拼接和比较都需要遍历字符,因此这种方法需要线性时间;与切片不同,它不会先通过切片创建反转后的副本。

使用循环检查 Python 字符串是否为回文

循环可以将每个字符与另一端对应位置的字符进行比较。右侧字符的索引是 len(word) - index - 1;只检查一半的位置就能覆盖所有字符对。

word = "radar"
result = True
for index in range(len(word) // 2):
    if word[index] != word[len(word) - index - 1]:
        result = False
        break
print(result)

一旦发现一对字符不同,循环就会立即停止。它的工作量与字符串长度成线性关系,而且无需创建反转后的副本。

使用递归检查 Python 字符串是否为回文

递归先比较两端的字符,然后用中间的子字符串再次调用同一个函数。长度小于 2 的字符串是基本情况:此时没有两端字符可以不相同。

def is_palindrome(text):
    if len(text) < 2:
        return True
    return text[0] == text[-1] and is_palindrome(text[1:-1])

print(is_palindrome("level"))

这个版本适合学习如何把问题拆解成更小的检查。每次调用都会切出一个子字符串,增加复制操作;输入过长时还可能超过 Python 的递归限制。一般的应用代码建议使用切片或循环方法。

使用 deque 检查 Python 字符串是否为回文

collections.deque 是一种双端队列。检查时可以从两端各取出一个字符,并比较这两个字符。创建双端队列并检查所有字符对,整体需要线性时间。

from collections import deque

def is_palindrome(text):
    chars = deque(text)
    while len(chars) > 1:
        if chars.popleft() != chars.pop():
            return False
    return True

print(is_palindrome("radar"))

单次从队列两端移除元素是常数时间操作,但完整检查并非常数时间:它可能需要处理每个字符。这种方法比较的是原始字符,因此大小写、空格和标点都会参与比较。

检查回文时忽略大小写和非字母数字字符

检查短语形式的回文时,可以先将文本转换为小写,再只保留字母数字字符。这会改变回文的判定方式:大小写、空格和标点不再影响比较,而字母和数字仍会参与比较。

def is_palindrome(text):
    normalized = "".join(char.lower() for char in text if char.isalnum())
    return normalized == normalized[::-1]

phrase = "A man, a plan, a canal, Panama!"
print(is_palindrome(phrase))

isalnum() 会保留字母和数字。Python 的字符串方法支持 Unicode 字符;如果应用只接受特定字母表,应明确规定所接受字符的范围。

选择一种 Python 回文检查方法

如果要用最简短的方式原样检查,可使用 word == word[::-1]。需要基于迭代器的替代方案时,可以将 reversed() 与 join() 配合使用;如果显式比较字符对并在发现不匹配时提前退出更清晰,也可以使用循环。deque 同样可以从两端比较字符。递归主要用于教学,因为每次调用都会切片文本,而且长输入可能触及递归限制。

请先决定是按原样比较输入,还是先对其进行规范化;这会决定大小写、空格和标点是否影响结果。有关文本处理的更多技巧,请参阅 Python 正则表达式(regex)。