零基础入门学习Python(第2版)
上QQ阅读APP看书,第一时间看更新

5.3 字符串

视频讲解

或许现在又回过头来谈字符串,有些读者可能会觉得没必要。其实关于字符串,还有很多你可能不知道的秘密,由于字符串在日常使用中是如此常见,因此小甲鱼抱着负责任的态度在本节把所知道的都与大家分享一下。

在一些编程语言中,字符和字符串是两个不同的概念,如C语言使用单引号将字符括起来,使用双引号包含字符串。但在Python中,只有字符串这一个概念:

     >>> str1 = "I love FishC.com!"
     >>> str1
     'I love FishC.com!'

注意:

可以使用单引号将字符串包裹起来,也可以使用双引号,但务必要成对编写,不能一边是单引号而另一边是双引号。

在学习了列表和元组之后,我们掌握了一个新的操作——切片,事实上也可以应用到字符串上:

     >>> str1[7:]
     'FishC.com!'

字符串与元组一样,都是属于“一言既出,驷马难追”的家伙。所以,一旦确定下来就不能再对它进行修改。如果非要这么做,仍然可以利用切片和拼接来实现:

     >>> str2 = "一只穿云箭,千军万马来相见!"
     >>> str2 = str2[:1] + '支' + str2[2:]
     >>> str2
     '一支穿云箭,千军万马来相见!'

注意:

这种通过拼接旧字符串的各个部分组合得到新字符串的方式,并不是真正意义上的修改字符串。原来的那个旧的字符串其实还在,只不过我们将变量名指向了拼接后的新字符串。旧的字符串一旦失去了变量的引用,就会被Python的垃圾回收机制释放掉。

比较操作符、逻辑操作符、成员关系操作符的操作和列表、元组是一样的,这里就不再赘述。

5.3.1 各种内置方法

列表和元组都有一些内置方法,大家可能觉得它们的方法已经非常多了,其实字符串的方法更多。表5-1总结了字符串的所有方法及对应的含义。

表5-1 Python字符串的方法及含义

续表

这里选几个常用的字符串方法给大家演示一下用法,其他的可以根据上述文档的注释依葫芦画瓢。

casefold()方法用于将字符串中所有的英文字母修改为小写:

     >>> str1 = "FishC"
     >>> str1.casefold()
     'fishc'

提示:

只要涉及字符串修改的方法,并不是修改原字符串,而是返回字符串修改后的一个拷贝。

count(sub[,start[,end]])方法用于查找sub参数在字符串中出现的次数,可选参数start和end表示查找的范围:

     >>> str2 = "上海自来水来自海上"
     >>> str2.count('上')
     2
     >>> str2.count('上', 0, 5)
     1

find(sub[,start[,end]])或index(sub[,start[,end]])方法用于查找sub参数在字符串中第一次出现的位置,如果找到了,返回位置索引值;如果找不到,find()方法会返回-1,而index()方法会抛出异常(注:异常是可以被捕获并处理的错误):

replace(old,new[,count])方法用于将字符串中的old参数指定的字符串替换成new参数指定的字符串:

     >>> str4 = "I love you."
     >>> str4.replace("you", "fishc.com")
     'I love fishc.com.'

split(sep=None, maxsplit=-1)方法用于拆分字符串:

     >>> str5 = "肖申克的救赎/1994年/9.6分/美国"
     >>> str5.split(sep='/')
     ['肖申克的救赎', '1994年', '9.6分', '美国']

和split()方法相反,join(iterable)方法用于拼接字符串:

     >>> countries = ['中国', '俄罗斯', '美国', '日本', '韩国']
     >>> '-'.join(countries)
     '中国-俄罗斯-美国-日本-韩国'
     >>> ','.join(countries)
     '中国,俄罗斯,美国,日本,韩国'
     >>> ''.join(countries)
     '中国俄罗斯美国日本韩国'

这种语法看上去可能会比较奇怪,很多读者可能会觉得被拼接的对象应该放在join()方法的左侧更合适(如写成这样countries.join('-'))?

但是因为join()被指定为字符串的其中一个方法,所以只能这么写。另外还有一个重要的原因是,join()的参数支持一切可迭代对象(如列表、元组、字典、文件、集合或生成器等),如果将它们写在左侧,那就必须为这些对象都创建一个join()方法,显然这样做是没有必要的。

其实,Python程序员更喜欢使用join()方法代替加号(+)来拼接字符串,这是因为使用加号(+)去拼接大量的字符串,效率相对会比较低,这种操作会频繁进行内存复制和触发垃圾回收机制。

5.3.2 格式化

视频讲解

什么是字符串的格式化,又为什么需要对字符串进行格式化?讲个小故事给大家听:某天小甲鱼心血来潮,试图召开一个“鱼C跨物种互联交流大会”,到会的朋友有来自各个物种的精英人士,有小乌龟、喵星人、汪星人,当然还有米奇和唐老鸭,那气势简直跟小甲鱼开了个动物园一样……但是问题来了,大家交流起来简直是鸡同鸭讲,不知所云!不过最后聪明的小甲鱼还是把问题给解决了,其实也很简单,各界都找一个翻译就行了,统一将发言都翻译成普通话,那么问题就解决了……最后我们这个大会当然取得了成功并被载入了“吉尼斯世界动物大全”。

好吧,举这个例子其实就是想跟大家说,格式化字符串,就是按照统一的规格去输出一个字符串。如果规格不统一,就很可能造成误会,例如,十六进制的10跟十进制的10或二进制的10完全是不同的概念(十六进制的10等于十进制的16,二进制的10却等于十进制的2)。字符串格式化,正是帮助我们纠正并规范这类问题而存在的。

1. format()

format()方法接收位置参数和关键字参数(位置参数和关键字参数在第6章中有详细讲解),二者均传递到一个名为replacement的字段。而这个replacement字段在字符串内用大括号({})表示。先看一个例子:

     >>> "{0} love {1}.{2}".format("I", "FishC", "com")
     'I love FishC.com'

怎么回事呢?仔细看一下,字符串中的{0}、{1}和{2}应该与位置有关,依次被format()的三个参数替换,那么format()的三个参数就称为位置参数。那什么是关键字参数呢?再来看一个例子:

     >>> "{a} love {b}.{c}".format(a="I", b="FishC", c="com")
     'I love FishC.com'

{a}、{b}和{c}就相当于三个目标标签,format()将参数中等值的字符串替换进去,这就是关键字参数。另外,也可以综合位置参数和关键字参数在一起使用:

     >>> "{0} love {b}.{c}".format("I", b="FishC", c="com")
     'I love FishC.com'

但要注意的是,如果将位置参数和关键字参数综合在一起使用,那么位置参数必须在关键字参数之前,否则就会出错:

     >>> "{a} love {b}.{0}".format(a="I", b="FishC", "com")
     SyntaxError: non-keyword arg after keyword arg

如果要把大括号打印出来,有办法吗?没错,这与字符串转义字符有点像,只需要用多一层大括号包起来即可:

     >>> "{{0}}".format("不打印")
     '{0}'

位置参数“不打印”没有被输出,这是因为{0}的特殊功能被外层的大括号({})所剥夺,因此没有字段可以输出。注意,这并不会产生错误哦。最后来看另一个例子:

     >>> "{0}:{1:.2f}".format("圆周率", 3.14159)
     '圆周率:3.14'

可以看到,位置参数{1}跟平常有些不同,后边多了个冒号。在替换域中,冒号表示格式化符号的开始,“.2”的意思是四舍五入到保留两位小数点,而f的意思是浮点数,所以按照格式化符号的要求打印出了3.14。

2. 格式化操作符:%

刚才讲的是字符串的格式化方法,现在来谈谈字符串所独享的一个操作符:%。有人说,这不是求余数的操作符吗?是的,没错。当%的左右均为数字的时候,它表示求余数的操作;但当它出现在字符中的时候,它表示的是格式化操作符。表5-2列举了Python的格式化符号及含义。

表5-2 Python格式化符号及含义令

下面给大家举几个例子供参考:

     >>> '%c' % 97
     'a'
     >>> '%c%c%c%c%c' % a
     'FishC'
     >>> '%d转换为八进制是:%o' % (123, 123)
     '123转换为八进制是:173'
     >>> '%f用科学计数法表示为:%e' % (149500000, 149500000)
     '149500000.000000用科学计数法表示为:1.495000e+08'

所以,使用格式化的方法也可以对字符串进行拼接:

     >>> str1 = "一支穿云箭,千军万马来相见;"
     >>> str2 = "两副忠义胆,刀山火海提命现。"
     >>> "%s%s" % (str1, str2)
     '一支穿云箭,千军万马来相见;两副忠义胆,刀山火海提命现。'

那么结合前面提到的两种方法,现在共有三种方法可以对字符串进行拼接了。什么时候用哪种方法,根据不同情况,可以参考下面三条准则进行选择:

• 简单字符串连接时,直接使用加号(+),例如:full_name = prefix + name。

• 复杂的,尤其有格式化需求时,使用格式化操作符(%)进行格式化连接,例如:result = "result is %s:%d" % (name, score)。

• 当有大量字符串拼接,尤其发生在循环体内部时,使用字符串的join()方法无疑是最棒的,例如:result = "".join(iterator)。

另外,Python还提供了格式化操作符的辅助指令,如表5-3所示。

表5-3 格式化操作符的辅助命令

同样给大家举几个例子供参考:

     >>> '%5.1f' % 27.658
     ' 27.7'
     >>> '%.2e' % 27.658
     '2.77e+01'
     >>> '%10d' % 5
     '         5'
     >>> '%-10d' % 5
     '5         '
     >>> '%010d' % 5
     '0000000005'
     >>> '%#X' % 100
     '0X64'
3. Python的转义字符及含义

Python的部分转义字符已经使用了一段时间,是时候来总结一下了,如表5-4所示。

表5-4 转义字符及含义