所以你施舍的时候,不可在你前面吹号,像那假冒为善的人,在会堂里和街道上所行的,故意要得人的荣耀。我实在告诉你们,他们已经得了他们的上次。你施舍的时候,不要叫左手知道右手所作的。要叫你施舍的事行在暗中,你父在暗中察看,必然报答你。(MATTHEW 6:2-4)
字符串(4)
虽然已经对字符串有了了解,但,因为人对字符串的要求比较多,特别是在输出格式上,要满足一定的样式要求。
字符串格式化输出
什么是格式化?在维基百科中有专门的词条,这么说的:
格式化是指对磁盘或磁盘中的分区(partition)进行初始化的一种操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。
不知道你是否知道这种“格式化”。显然,此格式化非我们这里所说的,我们说的是字符串的格式化,或者说成“格式化字符串”,表示的意思是:
格式化字符串,是C、C++等程序设计语言printf类函数中用于指定输出参数的格式与相对位置的字符串参数。其中的转换说明(conversion specification)用于把随后对应的0个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其它字符原样输出。
这也是来自维基百科的定义。在这个定义中,是用C语言作为例子,并且用了其输出函数来说明。在Python中,也有同样的操作——print
语句(Python 2)、print()
函数(Python 3),此前我们已经了解一二了。此处将详述之。
如果将维基百科的定义再通俗化,所谓字符串格式化化,就是要先制定一个模板,在这个模板中某个或者某几个地方留出空位来,然后在那些空位填上字符串,并且在显示结果中,字符串要符合空位置所设定的约束条件。
那么,那些空位,需要用一个符号来表示,这个符号通常被叫做占位符(仅仅是占据着那个位置,并不是输出的内容)。
>>> "I like %s"
'I like %s'
在这个字符串中,有一个符号:%s
,就是一个占位符,这个占位符可以被其它的字符串代替。比如:
>>> "I like %s" % "python"
'I like python'
>>> "I like %s" % "Pascal"
'I like Pascal'
这是曾经较为常用的一种字符串输出方式。注意“曾经”,言下之意,现在不怎么太提倡了。
的确如此,现在提倡使用.format()
,这是自Python 2.6开始引入的。所以,从现在开始,本教程详细介绍string.format()
的使用方法,而对用%
进行格式化输出的方式,仅仅局限在上面的样式。读者在阅读其它代码的时候,也能遇到使用%
的,那时候你心中默默说一句“落伍了”,然后翻译成string.format()
即可。
.format()
是字符串的一个方法。你在交互模式中,输入dir(str)
,会看到如下的内容:
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
这里所列出来的,就是字符串str
的所有属性和方法。
在这里先下一点毛毛雨。在Python中一切皆对象,所谓对象,就是一个具体东西。桌椅板凳,花花草草,动物植物,包括人,还有程序要找的那个“对象”,都是对象(不用追求严格定义,暂且模模糊糊知道大概即可,大概都不知道,也无妨),凡是对象都有属性和方法(至于属性和方法的定义,待后面说明)。刚才用dir(str)
所返回的结果,就是字符串的属性和方法。
在返回结果中,别的先不看,只看format
。有你的慧眼找一找,有没有发现?
继续不要离开交互模式,输入:
>>> help(str.format)
这是要看字符串的format()
方法的文档。只有通过阅读文档,我们才能了解它使做什么的。
返回结果是:
Help on method_descriptor:
format(...)
S.format(*args, **kwargs) -> str
Return a formatted version of S, using substitutions from args and kwargs.
The substitutions are identified by braces ('{' and '}').
S.format(*args, **kwargs)
,重点看括号里面的,*args
表示传入一种类型的参数,**arg
表示传入另外一种类型的参数。
又遇到新名词——参数——还是不用搭理它,只管继续——因为“发展是硬道理”!
你暂且阅读文档,不理解也没关系。下面用示例来说明使用方法。
>>> "I like {0} and {1}".format("python", "canglaoshi")
'I like python and canglaoshi'
在交互模式中,输入了字符串"I like {0} and {1}"
,并且其中用{0}
和{1}
占据了两个位置,它们就是占位符。然后使一个非常重要的点.
。
这个点.
非常重要,它是从对象引出它的属性或方法的工具,就如同汉语中的“的”一样。
比如“老齐的爱好”,“老齐”是那个对象,“爱好”就是一个方法,两者中间的那个“的”就相当于一个英文的点.
,于是可以写成老齐.爱好
,就可以表明上述的含义了。
format("python", "canglaoshi")
是字符串格式化输出的方法,传入了两个字符串,它们分别对应这"I like {0} and {1}"
里的那两个占位符,而且使按照顺序对应的,即第一个参数传入的"pytohn"
,对应着{0}
,第二参数传入的"canglaoshi"
对应着{1}
。
你还可以这样试试,就理解更深刻了。
>>> "I like {1} and {0}".format("python", "canglaoshi")
'I like canglaoshi and python'
请仔细观察找区别。
format()
方法的返回值是一个字符串——`'I like python and canglaoshi'`。
再对照help(str.format)
得到的文档,看一看,是不是理解文档的含义了呢?
一定要会阅读文档,这是学习语言的根本。
既然是“格式化”,就要指定一些格式,让输出的结果符合指定的样式。
>>> "I like {0:10} and {1:>15}".format("python", "canglaoshi")
'I like python and canglaoshi'
现在有格式了。{0:10}
表示第一个位置,有10个字符那么长,并且放在这个位置的字符是左对齐;{1:>15}
表示第二个位置,有15个字符那么长,并且放在这个位置的字符是右对齐。
>>> "I like {0:^10} and {1:^15}".format("python", "canglaoshi")
'I like python and canglaoshi '
现在是居中对齐了。
>>> "I like {0:.2} and {1:^10.4}".format("python", "canglaoshi")
'I like py and cang '
这个有点复杂,我们一点一点的解释。
{0:.2}
:0
说明是第一个位置,对应传入的第一个字符串。.2
表示对于传入的字符串,截取前两个,并放到第一个位置,注意的是,在:
后面和.
号前面,没有任何数字,意思是该位置的长度自动适应即将放到该位置的字符串。
{1:^10.4}
:1
说明是第二个位置,对应传入的第二个字符串。^
表示放到该位置的字符串要居中;10.4
表示该位置的长度是10个字符串那么长,但,即将放入该位置的字符串应该仅仅有4个字符那么长,也就是要从传入的字符串"canglaoshi"
中截取前四个字符,即为"cang"
。
再看结果,对照上述解释。
向format()
中,除了能够传入字符串,还可以传入数字(包括整数和浮点数),而且也能有各种花样。
>>> "She is {0:d} years old and the breast is {1:f}cm".format(28, 90.1415926)
'She is 28 years old and the breast is 90.141593cm'
{0:d}
表示在第一个位置放一个整数;{1:f}
表示在第二个位置放一个浮点数,那么浮点数的小数位数,是默认的。下面在这个基础上,可以再做一些显示格式的优化。
>>> "She is {0:4d} years old and the breast is {1:6.2f}cm".format(28, 90.1415926)
'She is 28 years old and the breast is 90.14cm'
{0:4d}
表示第一个位置的长度是4个字符,并且默认状态下,填充到该位置的整数是右对齐。
{1:6.2f}
表示第二个位置的长度使6个字符,并且填充到该位置的浮点数要保留两位小数,默认也是右对齐。
>>> "She is {0:04d} years old and the breast is {1:06.2f}cm".format(28, 90.1415926)
'She is 0028 years old and the breast is 090.14cm'
{0:04d}
和{1:06.2f}
与前述例子不同的在于在声明位置长度的数字前面多了0
,其含义是在数字前面,如果位数不足,则补0
。
以上的输出方式中,我们只讨论了format(*args, **kwargs)
中的*args
部分。还有另外一种方式,则是与**kwargs
有关的(关于这两种参数的含义,本教程后面有专门介绍)。
>>> "I like {lang} and {name}".format(lang="python", name="canglaoshi")
'I like python and canglaoshi'
一种被称为“字典格式化”,这里仅仅列一个例子。关于“字典”,本教程后续会有的。
>>> data = {"name":"Canglaoshi", "age":28}
>>> "{name} is {age}".format(**data)
'Canglaoshi is 28'
用format()
做字符串格式化输出,真的很简洁,堪称优雅。
但format()
毕竟只是字符串的方法之一,还有更多方法等待研究。
常用的字符串方法
字符串的方法很多,前面已经通过dir(str)
查看过了。
那么多方法,不会一一介绍,要了解某个具体的含义和使用方法,最好是使用help()
函数查看。再举例:
>>> help(str.isalpha)
Help on method_descriptor:
isalpha(...)
S.isalpha() -> bool
Return True if all characters in S are alphabetic
and there is at least one character in S, False otherwise.
按照这里的说明,就可以在交互模式下进行实验。
>>> "python".isalpha() #字符串全是字母,应该返回True
True
>>> "2python".isalpha() #字符串含非字母,返回False
False
根据分隔符分割字符串
split()
的作用是将字符串根据某个分割符进行分割。
>>> a = "I LOVE PYTHON"
>>> a.split(" ")
['I', 'LOVE', 'PYTHON']
这是用空格作为分割,得到了一个名字叫做列表(list)的返回值,关于列表的内容,后续会介绍。还能用别的分隔吗?
>>> b = "www.itdiffer.com"
>>> b.split(".")
['www', 'itdiffer', 'com']
去掉字符串两头的空格
有的朋友喜欢输入结束的时候敲击空格,比如让他输入自己的名字,输完了,他来个空格。有的则喜欢先加一个空格,总做的输入的第一个字前面应该空两个格。
这些空格是没用的。
Python考虑到有不少人可能有这个习惯,因此就帮助程序员把这些空格去掉。
方法是:
S.strip()
:去掉字符串的左右空格S.lstrip()
:去掉字符串的左边空格S.rstrip()
:去掉字符串的右边空格
例如:
>>> b = " hello " #两边有空格
>>> b.strip()
'hello'
>>> b
' hello '
特别注意,原来的值没有变化,而是新返回了一个结果。
>>> b.lstrip() #去掉左边的空格
'hello '
>>> b.rstrip() #去掉右边的空格
' hello'
字符大小写的转换
对于英文,有时候要用到大小写转换。最有名驼峰命名,里面就有一些大写和小写的参合。如果有兴趣,可以来这里看自动将字符串转化为驼峰命名形式的方法。
在Python中有下面一些字符串的方法,用来实现各种类型的大小写转化
S.upper()
:S中的字母大写S.lower()
:S中的字母小写S.capitalize()
:首字母大写S.isupper()
:S中的字母是否全是大写S.islower()
:S中的字母是否全是小写S.istitle()
:S中字符串中所有的单词拼写首字母是否为大写,且其他字母为小写(标题都这么写)
看例子:
>>> a = "qiwsir,python"
>>> a.upper() #将小写字母完全变成大写字母
'QIWSIR,PYTHON'
>>> a #原数据对象并没有改变
'qiwsir,python'
>>> b = a.upper()
>>> b
'QIWSIR,PYTHON'
>>> c = b.lower() #将所有的字母变成小写字母
>>> c
'qiwsir,python'
>>> a
'qiwsir,python'
>>> a.capitalize() #把字符串的第一个字母变成大写
'Qiwsir,python'
>>> a #原数据对象没有改变
'qiwsir,python'
>>> b = a.capitalize() #新建立了一个
>>> b
'Qiwsir,python'
>>> a = "qiwsir,github"
>>> a.istitle()
False
>>> a = "QIWSIR" #当全是大写的时候,返回False
>>> a.istitle()
False
>>> a = "qIWSIR"
>>> a.istitle()
False
>>> a = "Qiwsir,github" #如果这样,也返回False
>>> a.istitle()
False
>>> a = "Qiwsir" #这样是True
>>> a.istitle()
True
>>> a = 'Qiwsir,Github' #这样也是True
>>> a.istitle()
True
>>> a = "Qiwsir"
>>> a.isupper()
False
>>> a.upper().isupper()
True
>>> a.islower()
False
>>> a.lower().islower()
True
再探究一下,可以这么做:
>>> a = "This is a Book"
>>> a.istitle()
False
>>> b = a.title() #这样就把所有单词的第一个字母转化为大写
>>> b
'This Is A Book'
>>> b.istitle() #判断每个单词的第一个字母是否为大写
True
用.join()
拼接字符串
用+
能够拼接字符串,除了这个还有别的。
当然,+
也不是什么情况下都能够如愿的。比如,将列表(关于列表,后续详细说,它是另外一种类型)中的每个字符(串)元素拼接成一个字符串,并且用某个符号连接,如果用“+”,就比较麻烦了(是能够实现的,麻烦)。
用字符串的.join()
方法拼接字符串,也是一个好选择。
>>> b
'www.itdiffer.com'
>>> c = b.split(".")
>>> c
['www', 'itdiffer', 'com']
>>> ".".join(c)
'www.itdiffer.com'
>>> "*".join(c)
'www*itdiffer*com'
这种拼接,是不是简单呢?
虽然不能把所有方法穷尽,但读者完全可以仿照上述流程研究其它方法。
字符串的问题还要继续,因为中文和英文还有很大区别。
如果你认为有必要打赏我,请通过支付宝:[email protected],不胜感激。