HackerRank: Capitalize! 笔记和题解

HackerRank Capitalize! 笔记和题解。Python 中 title(),split(),capitalize() 和 string.capwords() 使用详解。

然

Table of Contents

简介

这篇笔记是我在做 HackerRank: Capitalize! 时写下的,这道题虽然不难,但我错了三次。。。最主要的在于我没搞清楚 title(), capitalize(), 和 string.capwords() 的特别之处。

题目

题目要求给定一个 string S,将每个单词的第一个字符大写,比如 "alison heck" 变成 "Alison Heck"。$0 < len(S) < 1000$。这个 string 只会包括字母,数字和空格。

需要注意的是,只有第一个字符要大写,如果第一个字符是数字则保持原样,比如 "12abc" 应该保持为 "12abc"。

分析

title()

我第一个试的就是 title(),但是有一个特殊情况 fail 掉了。比如输入:

1a 2b
def solve(s):
	return s.title()

#输出:1A 2B

很明显不符合我们上面的要求,因为 title 是单词里遇到的第一个字母大写,不符合我们的要求。

split() 默认将连续的空格视为一个 separator

在讲 capitalize() 和 string.capwords 之前,我们需要讲一下这个点。

这句话是什么意思呢,我们来看下面这个例子:

s = "tom   and jerry"
l = s.split()

print(l)

#输出:['tom', 'and', 'jerry']

在这里我们没有传入任何参数给 split() 的。

而如果我们设置 split() 的 separator 参数为空格,结果是不一样的:

s = "tom   and jerry"
l = s.split(' ')

print(l)

#输出:['tom', '', '', 'and', 'jerry']

这里就是按照一个空格作为 separator 进行切割。这样有个好处就是,我们可以对每个切分后的 string 做处理,再直接用 "".join(s) 给连回来。

s = "tom   and jerry"
l = s.split(' ')

print(l)
print(" ".join(l))

输出:

['tom', '', '', 'and', 'jerry']
tom   and jerry

而如果是上面没有传入参数的版本,我们用 join 连接后就会变成:

s = "tom   and jerry"
l = s.split()

print(l)
print(" ".join(l))

输出:

['tom', 'and', 'jerry']
tom and jerry

这样就没有保持原本 tom 和 and 之间的空格比较长的特性。

capitalize()

capitalize() 会返回一个 string copy 是将 string 的第一个 character 大写,其它的保持小写。这个基本上就是我们想要的了。

但我写的时候就没有注意到 split 的问题,因此写出了这个错误代码

def solve():
    l = s.split()
    for i in range(len(l)):
    	l[i] = l[i].capitalize()
    return " ".join(l)

如果遇到上面 tom and jerry的问题,这个解法就跪了,因为我们本应该出的是:

Tom  and Jerry

而这个解法会出:

Tom and Jerry

少掉了一个空格。

string.capwords(s, sep=None)

string.capwords(s, sep) 有两个 parameters,一个是 s,也就是要处理的 string,另一个是 sep,等同于 split 的 separator。

这个 string.capwords 的功能是这样的,将传入的 s 进行 split(),split 后对每一个切开的 string 做 capitalize(),再将它们 join 起来。

如果没有传入 sep,则 split 按默认的来,join 则用一个空格将其组合。
如果传入 sep, 则 split 和 join 都会使用 sep 来进行切割和组合。

简单来说,没有传入 sep,就基本等同于我上面的 split 后 capitalized。

import string

s = "tom   and jerry"
print(string.capwords(s))

#输出:Tom And Jerry

而如果传入 sep 为一个空格:

import string

s = "tom   and jerry"
print(string.capwords(s, " "))

#输出:Tom   And Jerry

这完全就是我们想要的。

题解

所以这是我最后的答案:

import string

def solve(s):
	return string.capwords(s," ")

当然我们将前面的想法稍微修改也是可以的:

def solve(s):
	return " ".join(word.capitalize() for word in s.split(" "))

参考

HackerRankPython简单难度

Comments