一、python中os模块实现,及其内部源码
def longestCommonPrefix(strs) -> str:
# python 中 os 模块中的方法及其源码
# import os
# return os.path.commonprefix(strs)
if not strs:
return ''
s1 = min(strs)
s2 = max(strs)
for i, c in enumerate(s1):
if c != s2[i]:
return s1[:i]
return s1
二、一句代码实现分析
def longestCommonPrefix(strs) -> str:
result = ''
for i in zip(*strs):
if len(set(i)) == 1:
result += i[0]
else:
break
return result
代码原理:zip 之后,然后用 set 去重,如果set之后长度为1,就说明,多个字符串,在相同的位置,字符是一样的;(注意上面的 break,可能中间有字符会不一样)
考虑简化代码不要 for 循环,第一步想到了使用 filter
datas = zip(*strs)
def func(item):
return len(set(item)) == 1
filter(func, datas)
# 于是可以用 lambda 简化成如下
filter(lambda item: len(set(item)) == 1, datas)
# 然后再写一个列表推导式
[i[0] for i in filter(lambda item: len(set(item)) == 1, datas)]
# 最后用 join 连接起来
''.join([i[0] for i in filter(lambda item: len(set(item)) == 1, datas)])
看似一切进行得很顺利,于是测试
def longestCommonPrefix(strs):
print(list(filter(lambda item: len(set(item)) == 1, zip(*strs))))
当测试数据是 [‘adcg’, ‘ad33’, ‘adsgfd’],很顺利,得到正确答案 ad
当测试数据是 [‘adcg’, ‘ad3g’, ‘adsgfd’],得到答案 adg,这可不是最大公共前缀,也是上面代码写 break 的原因;
这个时候,想到了使用 takewhile,即使后面有 len(set(item)) == 1 的情况也没关系,于是又试了一下;
def longestCommonPrefix(strs):
from itertools import takewhile
print(''.join([i[0] for i in takewhile(lambda item: len(set(item)) == 1, zip(*strs))]))
测试案例 [‘adcg’, ‘ad3g’, ‘adsgfd’],可以很成功的得到正确答案,ad