偶然在一个群里看到了这个题目

输入一个字符串,如果这个字符串是顺读、倒读都相同(例如“上海自来水来自海上”、“ABCBA”)的回文,那么返回 True,反之返回 False

首次尝试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def is_pj(words):
origin_list = []
origin_list.extend(words)
print(origin_list)
reversed_list = origin_list
reversed_list.reverse()
print(reversed_list)
return origin_list == reversed_list

if __name__ == "__main__":
print('是回文' if is_pj('上海自来水来自上海') else '不是回文')

# ['上', '海', '自', '来', '水', '来', '自', '上', '海']
# ['海', '上', '自', '来', '水', '来', '自', '海', '上']
# 是回文

可以看出,我们的思路是正确的:首先将输入字符串展开到数组列表中,然后将列表反转然后与原列表进行比对,如果相同那么输入字符串就是回文。但是我们可以从第一次尝试中看出,两个列表之间使用 “==” 进行判断得到的是内存地址比对的结果,所以我们需要将列表处理为字符串再进行比对

改进代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def is_pj(words):
origin_list = []
origin_list.extend(words)
reversed_list = origin_list
reversed_list.reverse()
return list_to_str(origin_list) == list_to_str(reversed_list)


def list_to_str(lst:list):
lst.reverse()
result = ''
for s in lst:
result += s
return result


if __name__ == "__main__":
print('是回文' if is_pj('上海自来水来自海上') else '不是回文')

# 是回文

我们写了一个将列表转为字符串的方法,因为使用 for 将列表元素遍历追加到字符串中得到的结果是反的,所以我们在遍历之前将列表反序(reverse)。转换之后就可以直接比对字符串了,得到的结果正式我们需要的结果。

补充

在 Python3 中,可以使用 operator 模块中的 eq 方法直接判断两个 list 是否相等,那么我们的代码还可以简化

幻想中的简化:

1
2
3
4
5
6
7
8
9
10
11
12
13
import operator


def is_pj(words):
origin_list = []
origin_list.extend(words)
reversed_list = origin_list
reversed_list.reverse()
return operator.eq(origin_list, reversed_list)


if __name__ == "__main__":
print('是回文' if is_pj('上海自来水来自海上') else '不是回文')

事实上,现实是残酷的,下面是 operator.eq 的实现

1
2
3
def eq(a, b):
"Same as a == b."
return a == b

又水了一篇 哈哈哈哈嗝~