回文判断
回文(palindrome)是从左到右和从右到左读起来都一样的字符串。比如说,
racecar
和Live on time, emit no evil
都是回文。请注意,我们仅仅考虑字母和数字,且不分大小写。在得到输入字符串后,请判断它是否是回文。
# 范例行为 >>> is_palindrome("Step on no pets!") True >>> is_palindrome("'Tis not a palindrome") False >>> is_palindrome("Hi, I am Mai Ih") True
提示
str.isalnum返回某字符串是否纯粹由数字和字母字符组成(对单个字符的字符串也可以用)。
>>> "I love Python".isalnum() False >>> "IlovePython".isalnum() True
尝试将其与 str.lower
一起使用来过滤所有非数字字母符号并将所有字符小写化,然后再进行回文判断。
解
本题最简单的解如下。我们使用了 str.join
函数以及步距为负的切片:
def is_palindrome(input_str): """ 判断某字符串是否为回文。忽略空格, 字符大小写,以及非字母数字的字符 Parameters ---------- s: str 输入字符串 Returns ------- bool """ filtered_str = "".join(c.lower() for c in input_str if c.isalnum()) return filtered_str == filtered_str[::-1]
注意 (c.lower() for c in input_str if c.isalnum())
使用了有过滤条件的生成器理解。因此,
"".join(c.lower() for c in input_str if c.isalnum())
等值于以下的代码块:
filtered_str = "" for char in input_str: if char.isalnum(): filtered_str += char.lower()
生成器表达式不仅更加简短易读,且其对 str.join
的使用使得创建新列表更加高效。在以上代码块中每次调用 filtered_str += c.lower()
都会在内存中创建一个新字符串,而 str.join
在它消耗可迭代物时仅仅使用单个字符串。
接下来,请回忆,seq[::-1]
使用的步距-1的切片将会返回序列的反向版本。因此,filtered_str == filtered_str[::-1]
允许我们对比 filtered_str
中的第一个字符和原本字符串的倒数第一个字符,如此继续。因此,这等值于:
is_equal = True for i in range(len(filtered_str)//2): # 请回忆:5//2 -> 2, 6//2 -> 3 if filtered_str[i] != filtered_str[-(i+1)]: is_equal = False break
使用切片来进行这个对比的唯一坏处在于它需要复制一份 filtered_str
,而显性的for循环不需要。
在这里指出的效率考量仅仅在 is_palindrome
可能是我们整体代码的效率瓶颈时才值得进行。虽然我们希望读者能够发展编写高效Python代码的直觉,但我们不推荐读者为了过早地优化代码来将代码改得太过难懂。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论