在前面提起过字符串这个词,现在就来学习什么是字符串。
首先,字符串是python内置的数据类型,其特点是用引号引起来,并且可以是使用单引号('字符串'),双引号("字符串"),三个引号('''字符串''' 和"""字符串""")。注意,这些符号都是半角符号,且是英文的引号,也就是不能用中文输入法中的引号。
这些字符串在单独使用,且都是一行的时候,并没有任何差别,例如:
a = '123'
b = "123"
c = '''123'''
d = """123"""
str()
a = str('123')
print a
不过传参的时候还是要加引号,所以一般不这样创建。
上面几种写法是一种意思,另外,要注意引号引起来的都属于字符串类型,就算里面是数字或其他数据类型也一样。所以,当对字符串使用加法的时候,得到的不是数学上的相加,而是字符串的拼接。
如上所示,但一般我们不这样进行字符串的拼接,因为这里的拼接方法非常低效,浪费内存空间。例如:
a = '123' + '456'
'123' ,再创建 '456' ,然后将其拼接成 '123456'
1.字符串的拼接
其实还有一个使用+=符号的拼接方法,而且貌似效率不错,但我也是看别人的文章看到的,个人不是太清楚原理,所以就不说了)。
1.'io.StringIO',内存字符串IO拼接(从内存层面操作,用的很少,也没怎么了解过,这里不多说明)
2.str.join(),使用字符串的join()方法(str是创建字符串对象的类,到面向对象的时候会详细解释,这里看代码演示先)
a = '' #先创建一个空的字符串,按面向对象的说法叫创建对象
a.join(('abc','def')) #使用join()方法拼接字符串,而join()方法继承于父类
这里加入了从面向对象的解释,如果看不懂,可以在学完面向对象后回来,我当时学的时候也是一脸懵逼,但学完面向对象之后,我才有一种顿悟的感觉,以后我会分享我对面向对象的一些理解。
总结一下其的用法:
join()
str.join(sequence),其中sequence代表一个序列,在Python中有六种内建的序列:列表、元组、字符串、Unicode字符串、buffer对象和xrange对象(后面会有总结)。
也就是说除了像示例那样传一个元祖之外,还能传字符串,那么是否可以这样写呢:
b = ''
b.join('123','456')
答案是不可以,会出现报错,报错信息如下:
具体意思是,函数只要一个数据,我们却给了两个,所以报错了。
也就是说当我们这样写的时候,其实是传了两个序列进去,一个字符串就是一个序列。
那么,如果我们只传一个字符串呢?
好像没有问题,那当b不是空的时候呢?
坑爹啊这是),如果传的是元祖呢?
join()并没有改变b的值,只是返回了一个新对象,关于返回值会在函数中讲)
嗯,也是个大坑。
看来是在传入的序列后,按照索引逐一取出的值,在这些值之间插入原来的字符串。
教练,这个和说好的不一样啊!
其实我们有更好的方法,那就是字符串的格式化。
2.字符串的格式化
字符串格式化的原理是,我先在里面占着一个坑,但我暂时不填这个坑,等到要用的时候,在把要填的东西扔进去。
先看代码示例:
name = 'scolia'
a = '%s是一个帅哥' %name
print a
scolia使用了字符串格式化,效果拔群,scolia得到了‘帅哥’称号。
%s 就是所说的坑,而外面的 %name 就是我们要想要填入的东西,当然一般我们用变量来储存这个值,如果配合用户交互来动态改变name的值的话,那么人人都能是‘帅哥’了。
但这样我们还不满足,如果用户是女的呢?还用帅哥就不合适了吧。这个时候,我们可以多占几个坑。
name = 'scolia'
how = '帅哥'
a = '%s是一个%s' %(name,how)
print a
结果:
(要美女自己写)。
变量和占位符数量不对应是会报错的),而且是按顺序来取代里面的占位符的。
但如果我们不想按顺序来传呢?可以这样写:
a = '%(name)s是一个%(how)s' %{'how':'帅哥','name':'scolia'}
结果和上面的一样,用字典的方式传值,然后里面用字典的key去获取,关于字典的详细以后会讲。
%s 中的s是什么意思(你就当有人这样问,别吐槽),这里的s代表我将要用字符串来填这个坑,类似的,我们还可以有以下的写法:
格式 | 说明 |
%s | 字符串(str()形成的) |
%r | 字符串(repr()形式的) |
%d/%i | 有符号整数(十进制) |
%u | 无符号整数(十进制) |
%o | 无符号整数(八进制) |
%x | 无符号整数(十六进制) |
%X | 无符号整数(十六进制大写字符) |
%e | 浮点数字(科学计数法) |
%E | 浮点数字(科学计数法,用E代替e) |
%f/%F | 浮点数字(用小数点符号) |
%g | 浮点数字(根据值的大小采用%e或%f) |
%G | 浮点数字(类似于%g) |
%p | 指针(用十六进制打印值的内存地址) |
%n | 存储输出字符的数量放进参数列表的下一个变量中 |
%c | 转换成字符(ASCII 码值,或者长度为一的字符串) |
%% | 字符‘%’ |
这个表是我从网上找的,里面有那……么多类型,是不是我用什么去替换,就要用什么占位符呀,这么多这么记得住?
很多情况下一个 %s 就已经足够了,因为使用这个标记时,会将传入的数据先用 str() 方法转换为字符串,而python的所有数据类型都能转换成字符串(别人是这样写的),而最终要输出的结果又是字符串(不然怎么叫字符串的格式化)。
所以,占位符的格式可以总结为:
%[(name)][flags][width].[precision]typecode
[]代表可选,以后都是这样表示。
(name):用字典的key传值,上面有提到
typecode:数据类型,也就上面表的那些,一般%s就足够了,当然有需要可以用其他的。
可以有+,-,' '或0。+表示右对齐。-表示左对齐。' '为一个空格,0表示使用0填充。
表示显示宽度,在设置了宽度后,上面的各种对齐,填充才有效果。
这些对齐,填充,宽度是什么意思?首先,我有一个字符串'scolia',长度为6,可我硬要用10个字符的长度去显示怎么办,那是不是会多出4个位置,这4个位置怎 么办,是不是可以用空格或者0去填充。但这4个多出来的长度的位置是不是不确定的,那我可以先让原来的字符去占住位置,就是所谓的对齐,对齐后剩下的位置才是 填充的位置。
表示小数点后精度,配合浮点数使用。
当然,字符串的格式化还有其他方法,这里这就不继续深入了。
3.引号的嵌套
在开始的时候说过,当几种引号单独使用,且只有一行的时候,效果都一样。但是当其嵌套使用的时候,就要注意一些问题,看下面的示例:
a = 'scolia说:'我要说一句话'' #错误写法
这个时候,就会造成混乱了,就像这里的颜色标识一样,把前面的一段的当成是字符串了,而后面那段又不符合语法,肯定是会报错的。
所以,这个时候就要这么写了
a = 'scolia说:\'我要说一句话\''
print a
其中,\ 是转义符号,这里将有意义的引号(')转换成普通的符号,被转义后就失去了引起字符串的含义了。
结果也是我们想要的,但是每次都有进行转义实在太麻烦了,此时,我们可以这么做
a = "scolia说:'我要说一句话'"
print a
在外围使用双引号,在里使用单引号,这样里面的单引号就不会被解释成要创建字符串了。
当然倒过来也是可以的:
a = 'scolia说:"我要说一句话"'
print a
结果也是一样。
但是,有时候我们有这样的需求:
a = 'scolia说:"我要说一句话,这句话很长长长长长长长长长长长长长长长长长长长长长长长长长长长"'
print a
其结果是这样的:
但这句话太长了,我要进行换行这么办?
那就要这么写:
a = 'scolia说:"我要说一句话,这句话很长长长长长长长长长长\n长长长长长长长长长长长长长长长长长"'
print a
其结果是这样的:
其中,\n 的意思就是换行符(当然这里的 \ 也转义符,只不过是将原来没意义的字符变成有意义),到了这里就会换行,另外还要很多特殊字符,这里不逐一列举了。
但是每次换行的时候都要用 \n 实在太麻烦了,我写的时候自己换行不行吗?
很显然我的IDE用了红色波浪线表示这是个语法错误。
那我这样写
\ 符号表示我这行代码写不下了,我要换行再写(这个符号和linux命令中的一样),其结果是:
嗯……多了几个空格,那我再改改:
运行一下:
很好,空格是没了,然而,并没有什么卵用。
不甘心啊,难道就没有解决方法了吗?此时,三个引号表示:孩子,你还太年轻。
a = '''scolia说:"我要说一句话,这句话很长长长长长长长长长长
长长长长长长长长长长长长长长长长长"'''
print a
还是要注意单双引号的嵌套问题。
一看运行结果,竟然成了,这可真魔法。
这时,又有机智的人表示,三个引号不是注释的多行写法吗?为什么这里又能作为创建字符串的特殊符号,这样好混乱呀!
其实分辨三个引号里面写的到底是注释还是字符串有一个绝佳的方法,就是看它前面有没有赋值给某个变量,看那标准的赋值符号(=)。如果有赋值,那就是创建了字符串对象,没有,那就是注释了。
真是机智如我,这都被我发现了
好了,关于引号的问题就先讲到这里。
4.字符串的序列特性
都说字符串也是序列了,那么就可以用序列的方法去处理它了。
所有序列类型都可以进行某些特定的操作。这些操作包括:索引(indexing)、分片(sliceing)、加(adding)、乘 (multiplying)以及检查某个元素是否属于序列的成员(成员资格)。除此之外,Python还有计算序列长度、找出最大元素和最小元素的内建函数。
关于序列,以后会另起一篇进行说明,着急的话可以看看别人怎么写的先,或者你看我更新了后面的内容了没。
5.字符串的不可修改的
字符串是无法修改的,一旦从内存中生成,就无法改动它,任何试图改变它的操作,例如:
a = 'scolia'
#我突然想将第一个s大写
a[0] = 'S' #用索引的方法修改
其结果:
很明显不能,那我这样写呢?
a = 'scolia'
a = 'Scolia'
其实这样是等于重新赋值了,关于变量的赋值是怎么样的,可以看我之前的文章。
实际上原来的值还在内存之中,只不过改变的a变量的引用,让其指向新的值,而旧的值并没有改变,只是在内存中等待python的垃圾回收。
关于可修改和不可修改的数据类型,我后面也会有一个总结。
5.字符串的内建方法
这些方法又是一堆,有些人可能会死记硬背,但是我建议在学会了面向对象后再来回顾这些内容,到时候会有一种顿悟的感觉。
关于内建方法的总结又要另起一篇说明了,因为写到这里实在太长长长长了。
突然之间觉得自己好像挖了很多的坑,现在容我先休息一下……