2、流程控制及基本数据类型
赋值
序列解包
交换赋值
序列解包
星号解包
链式赋值
增强赋值
布尔值(Bool)
条件判断
短路
断言
循环语句
循环语句常用语法
For循环
序列迭代工具
zip并行迭代
enumerate索引迭代
正反迭代(sorted/reversed)
while循环语句
死循环
循环中子句
三元表达式
数字
计算函数
字符串(不可变类型)
字符串初始化
字符串特性
字符串方法
字符串格式化
内置模块字符串格式化
有序格式化
无序格式化
关键字参数格式化
列表元素格式化
字符串类型格式化
字符串格式类型
宽度
精度
宽度和精度
千位分隔符
填充
对齐
字符串拼接
str和repr
原始字符串
序列解包
交换赋值
序列解包
星号解包
链式赋值
增强赋值
布尔值(Bool)
条件判断
短路
断言
循环语句
循环语句常用语法
For循环
序列迭代工具
zip并行迭代
enumerate索引迭代
正反迭代(sorted/reversed)
while循环语句
死循环
循环中子句
三元表达式
数字
计算函数
字符串(不可变类型)
字符串初始化
字符串特性
字符串方法
字符串格式化
内置模块字符串格式化
有序格式化
无序格式化
关键字参数格式化
列表元素格式化
字符串类型格式化
字符串格式类型
宽度
精度
宽度和精度
千位分隔符
填充
对齐
字符串拼接
str和repr
原始字符串
赋值
即便是不起眼的赋值操作,其实也蕴藏着许多窍门,如序列解包、链式赋值、增强赋值等;
序列解包
对于赋值语句有的是给变量赋值,还有的给数据结构的一部分(如列表中的元素和切片,或字典项)赋值,其实还有其他的赋值语句,如下,可同时(并行)给多给变量赋值,这让函数能够返回被打包成元组的多个值,然后通过一条赋值语句轻松地访问这些值,这就是序列解包,序列解包是Python 3.0之后才有的语法,如下。
a, b, c = 1, 2, 3 # 等号右侧实际是个元组
print(a) # 1
print(a, c) # 1 3
交换赋值
变量的交换赋值,简单的说,就是两个甚至两个以上的变量值之间进行值的交换,比如,此时有A和B两个变量,需要将A的值赋值给B,将B的值赋值给A,此为交换赋值,以往的思维是首先将变量A的值临时存储,然后将B的值交给A,最后将临时存储的值,交给B从而实现变量交换,而在Python 3里面,进行了优化,直接使用如下的方式进行变量交换赋值;
a, b = 1, 2 # 变量定义
a, b = b, a # 交换赋值
print("a:%s,b:%s" % (a, b)) # a:2,b:1
序列解包
实际上,对于这么一种赋值方式,我们称之为序列解包(或可迭代对象解包),将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列的变量中,如下;
values = (1, 2, 3)
x, y, z = values
print("z:%s,y:%s,z:%s" % (x, y, z)) # z:1,y:2,z:3
这在使用返回元组(或其他序列或可迭代对象)的函数或方法时很有用。假设要从字典中随便获取一个键值对,可使用方法popitem,它随便获取一个键值对并以元组的方式返回。接下来,可直接将返回的元组解包到两个变量中;
users = {"name": "cce", "age": 18}
key, val = users.popitem()
print(key) # age
print(val) # 18
print(users) # {'name': 'cce'}
星号解包
对于序列解包来讲,要解包的序列里面的元素必须与等号左边列出的目标个数相同,否则Python将抛出异常,在这种情况下,我们可以使用星(*)号来收集多余的值,但是星(*)号是一个特殊字符,所以我们一般在星号后面接一个字符,表示,将星(*)号对应都所有都值都给这个字符变量,这样就无需确保值和变量的个数相同,赋值语句的右边可以是任何类型的序列,但是我们使用来星(*)号之后,最后都会返回一个列表,如果星(*)号没有匹配到任何值,那么将返回一个空列表;
举一反三,假设我们的序列是一个元组,里面的元素有4个,那么我们解包等号左边的解包字符是a,*other,b,那么结果将是a获得第一个值,b获得最后一个值,而other将获得中间两个值;
lst = [1, 2, 3, 4, 5]
first, *other, end = lst
print(first, end) # (1, 5)
print(other) # [2, 3, 4]
链式赋值
链式赋值是一种快捷方式,它是用一行语句将多个变量赋值为同一个值,语法如,变量1=变量2=变量n=赋值,这有点像前一节介绍的并行赋值,但并行赋值只涉及一个值;
x = y = (1, 2, 3)
# 上面的代表实际上等价于
y = (1, 2, 3)
x = y
# 但是需要注意的是,上面的语句和如下的语句,不能完全等价,因为下面的语句是完全独立赋值,上面则的将y的引用赋值给了x;
y = (1, 2, 3)
x = (1, 2, 3)
增强赋值
可以不编写代码x = x + 1,而将右边表达式中的运算符(这里是+)移到赋值运算符(=),的前面,从而写成x += 1。这称为增强赋值,适用于所有标准运算符,如*、/、%等;
x = 0
x = x + 1
print(x) # 1
# 上面是我们正常逻辑思想下,对一个数值进行固定值增加的时候做的方式,那么转换为增强赋值如下;
x = 0
x += 1
print(x) # 1
增强赋值也可用于其他数据类型(只要使用的双目运算符可用于这些数据类型);
x = "cce"
x += 'cfj'
x *= 2
print(x) # 'ccecfjccecfj'
布尔值(Bool)
布尔值即真值,真值也称为布尔值,一般主要用于布尔表达式(如用于if条件语句中),对于Flase、None、0、()、[ ]、{}都视为假值,这意味着任何Python值都可解释为真值。乍一看这有点令人迷惑,但也很有用。虽然可供选择的真值非常多,但标准真值为True和False,True和False不过是0和1的别名,虽然看起来不同,但作用是相同的;
print(True) # True
print(False) # False
print(True == 1) # True
print(False == 0) # True
print(True + False + 42) # 43
# 使用bool函数来验证布尔值是真值还是假值
print(bool(1)) # True
print(bool(0)) # False
因此,如果你看到一个返回1或0的表达式(可能是使用较旧的Python版本编写的),就知道这实际上意味着True或False,布尔值True和False属于类型bool,而bool与list、str和tuple一样,可用来转换其他的值;
条件判断
条件判断语句运行原理就是,给出条件,决定下一步怎么做,如果条件为真,就执行决策条件代码块的内容,为假就退出判断,结束判断语句,语法如下;
# 单分支
if condition:
body
---
# 双分支
if condition:
body
else:
body
---
# 多分支语句
if condition:
body
elif condition:
body
...
else:
body
短路
布尔运算符有个很有用的特征,也就是它只做必要的计算,例如,当x和y都为真值时,表达式 x and y才为真,如果x为假,那么整个表达式将立即返回假,而不关心y;
上面使用使用and来做计算的,其实还可以使用我们布尔运算符里面的or,如x为假,这个表达式返回x或者返回y,and和or一个是必须同时为真值,一个是有一个为真值即可,实际上,如果使用or来做或运算,当x为假时,这个表达式将返回y,这种行为被称为短路逻辑(或延迟求值);
>>> input('Please enter your name: ') or '<unknown>'
Please enter your name: cce
'cce'
>>> input('Please enter your name: ') or '<unknown>'
Please enter your name:
'<unknown>'
断言
断言(assertion)是一种在程序中的一阶逻辑(如:一个结果为真或假的逻辑判断式),目的为了表示与验证软件开发者预期的结果——当程序执行到断言的位置时,对应的断言应该为真。若断言不为真时,程序会中止执行,并给出错误信息;
而在Python中,if语句就可以实现所谓的断言,用if语句判断一个表达式,在表达式条件为False的时候触发异常,断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。
>>> assert 1==2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
如果知道必须满足特定条件,程序才能正确地运行,可在程序中添加assert语句充当检查点, 这很有帮助,还可在条件后面添加一个字符串,对断言做出说明;
>>> age = -1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: The age must be realistic
循环语句
循环语句可以遍历任何序列对象,如一个列表、一个字符串或者任何一个可迭代对象,循环语句主要有两种方式For、While,根据自己的需求选择不同方式进行循环处理;
循环语句常用语法
在循环语句的使用中,有三个常用的语法,分别为跳出循环、无操作和提前结束循环,如下;
continue:continue语句,表示结束此轮循环,进入下一次循环,继续往下执行;
break:break语句,表示跳出循环,也就是结束循环的意思,不往下继续执行;
pass:pass是空语句,pass不做任何事情,主要是为了保持程序结构的完整性,所以一般用来做占位符;
For循环
基本上,可迭代对象是可以使用for循环进行遍历对象的,Python中for循环可以遍历任何序列的项目,如一个列表或者一个字符串,同时for循环也支持所谓的else子句,循环中的else子句只有在循环正常结束时,才会被执行,所谓正常结束,就是没有因为break才跳出循环,即为正常结束,如下;
numbers=[1,2]
for num in numbers:
print(num)
else:
print("end")
# 1
# 2
# end
序列迭代工具
在Python中迭代序列时,有一些函数非常好用。有些函数位于itertools模块中,还有一些Python的内建函数十分方便。
zip并行迭代
zip函数用于将可迭代的对象作为参数,它可以将多个序列(列表、元组、字典、集合、字符串以及 range() 区间构成的列表)“压缩”成一个zip对象。所谓“压缩”,其实就是将这些序列中对应位置的元素重新组合,生成一个个新的元组;
返回一个zip对象,这个zip对象其实是一个可迭代对象,同时也是一个生成器,我们可以使用next或者for循环来依次取出该对象里面的元祖,惰性求值;
有时候,可能会有这样的需求,同时迭代两个序列,依次取出两个或者多个序列中的相同索引的值,进行拼接,正常的思维会如下这样做;
lst1=["cce","cfj"]
lst2=[18,10]
for index in range(len(lst1)):
print("name: %s,age: %s" %(lst1[index],lst2[index]))
# name: cce,age: 18
# name: cfj,age: 10
其实,对于Python有一个很有用的内置迭代工具zip,它可以将两个或多个序列“缝合”起来,一一对应,并返回一个由元组组成的序列,返回值是一个适合迭代的对象,要查看其内容可以使用list函数将其结果转换为列表;
lst1 = ["cce", "cfj"]
lst2 = [18, 10]
lst3 = ['1', '1']
print(list(zip(lst1, lst2, lst3))) # [('cce', 18, '1'), ('cfj', 10, '1')]
# “缝合”后,可在循环中将元组解包;
lst1 = ["cce", "cfj"]
lst2 = [18, 10]
for name, age in list(zip(lst1, lst2)):
print(name, age)
# cce 18
# cfj 10
- 注意:
需要注意的是,函数zip可用于“缝合”任意数量的序列。但是当序列的长度不同时,函数zip将在最短的序列迭代完后停止“缝合”,剩下元素较多的序列剩下的元素将被抛弃;
enumerate索引迭代
在有些情况下,可能需要在迭代序列对象的同时获取迭代出的元素在序列中的索引。例如,你可能想替换一个字符串列表中所有包含子串'xxx'的字符串。当然,完成这种任务的方法有很多;
lst = ['ce', 'sd', 'cce', 'cfg', 'asd']
for string in lst:
if 'cce' in string:
index = lst.index(string) # 在字符串列表中查找字符串 lst[index] = '[censored]'
lst[index] = '[censored]'
print(lst) # ['ce', 'sd', '[censored]', 'cfg', 'asd']
上述方法可以实现,但看起来也有点笨拙,有点鸡肋。那么Python给我们提供了更好的解决方法,Python的内置函数enumerate,就主要是用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标;
lst = ['ce', 'sd', 'cce', 'cfg', 'asd']
for index, string in enumerate(lst): # enumerate会返回两个值,第一个是迭代值当前的索引号,第二个是索引值
if 'cce' in string:
lst[index] = '[censored]'
print(lst) # ['ce', 'sd', '[censored]', 'cfg', 'asd']
正反迭代(sorted/reversed)
reversed为反转,即将序列的元素原地倒叙修改,sorted即,将数据进行排序,应该是根据ASCII码来排序的。它们类似于列表方法reverse和sort(sorted接受的参数也与sort类似),但可用于任何序列或可迭代的对象,且不就地修改对象,而是返回反转和排序后的版本;
需要注意的是,sorted返回一个列表,而reversed像zip那样返回一个更神秘的可迭代对象。无需关心这到底意味着什么,只管在for循环或join等方法中使用它,不会有任何问题。只是不能对它执行索引或切片操作,也不能直接对它调用列表的方法。要执行这些操作,可先使用list对 返回的对象进行转换;
同时,sorted支持两个参数,参数一reversed,即反转的意思,表示是否经过排序之后,还要再反转一次,参数二,key,它接收一个函数,key指定的函数将作用于可迭代对象的每一个元素上,并根据key指定的函数返回的结果进行排序。这个函数也仅仅用来排序,不会影响原始数据,最后返回的也就说使用函数排序之后还原的原始数据。
# sorted # 排序
data = [
{"name": "cce", "age": 22, "height": 170},
{"name": "cfj", "age": 18, "height": 80},
{"name": "dwc", "age": 10, "height": 120}
]
# 根据年龄排序
print(sorted(data, key=lambda item: item.get("age"))) # [{'height': 120, 'age': 10, 'name': 'dwc'}, {'height': 80, 'age': 18, 'name': 'cfj'}, {'height': 170, 'age': 22, 'name': 'cce'}]
# 根据身高排序
print(sorted(data, key=lambda item: item.get("height"))) # [{'height': 80, 'age': 18, 'name': 'cfj'}, {'height': 120, 'age': 10, 'name': 'dwc'}, {'height': 170, 'age': 22, 'name': 'cce'}]
# reversed 反转,不排序
lst=[1,2,3,4]
print(list(reversed(lst))) # [4, 3, 2, 1]
while循环语句
Python编程中while语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务;
count=0
while count <= 10:
print('count is',count)
count+=1
死循环
因为只要条件为真,循环语句就不会停止,所以一般来讲,我们也可以通过这个特性来创建一个死循环进程,如下;
while True:
print('死循环')
或者
while 1 == 1:
print('死循环')
循环中子句
通常,在循环中使用break是因为你“发现”了什么或“出现”了什么情况。要在循环提前 结束时采取某种措施很容易,但有时候你可能想在循环正常结束时才采取某种措施。如何判断循环是提前结束还是正常结束的呢?可在循环开始前定义一个布尔变量并将其设置为False,再在跳 出循环时将其设置为True。这样就可在循环后面使用一条if语句来判断循环是否是提前结束的;
broke_out = False
for x in seq:
do_something(x)
if condition(x):
broke_out = True
break
do_something_else(x)
if not broke_out:
print("I didn't break out!")
一种更简单的办法是在循环中添加一条else子句,它仅在没有调用break时才执行。继续前面讨论break时的示例;
# 打印出了“no break”,表示该循环是正常退出,并没有使用break语句跳出循环
lst=[1,2,3]
for num in lst:
if num == 4:
break
print(num)
else:
print("no break")
1
2
3
no break
三元表达式
三元表达式其实是从C语言中学习过来的,C语言里面有一个三元运算符,但是Python对其进行了改进,使用了if else进行了改进,真值在前,假值在后;
print("cce" if 1==2 else "cfj") # cfj
# 真值放在前面,假值放在后面
数字
数字类型的数据是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间,那么对于数字类型都有很多常见的预算符重载,如下列表;
+ : 加法运算;
- : 减法运算;
* : 乘法运算;
/ : 除法运算;
** : 求次方;
% : 求余数;
// : 求商;
计算函数
上面的案例使用了**来实现求此方,其实Python3内置了有求此方的内置函数,以及其他内置函数;
# 求次方
print(pow(2,10)) # 1024
# 求绝对值
print(abs(-10)) # 10
# 四舍五入
print(round(1.3)) # 1
字符串(不可变类型)
字符串可以看成是一个个字符组成的有序的序列,比如列表、元祖也是序列,内部是一个个元素,只不过对字符串来讲,它是一个个字符,那么这一个个字符组织成一起,就变成了序列,这个序列在内存中也是连续摆放的,类似列表,一个字符挨着下一个字符;
它是字符的一个集合,同时它也是一个容器,只不过这个容器是不可变,即,字符串是不可变的数据类型,一旦定义了它就是一个字面常量,将不允许再被修改,它类似元祖,也支持索引操作,切片操作和迭代操作;
有序序列都可以使用索引,因为他们是顺序排放,通过编号整齐排列的,字符串是一个字符序列,列表是一个有序序列,元祖是不可变的有序序列 ;
字符串初始化
字符串可以使用单引号、双引号和三引号三种方式,来进行表示,在遇到特殊情况可以使用r前缀或者\\转义符来表示,尤其是在引号里面包含引号的时候,需要用到;
str1="str1"
str2='''str2'''
str3=str("str3")
print(str1,str2,str3) # str1 str2 str3
字符串特性
所有标准序列操作(索引、切片、乘法、成员资格检查、长度、最小值和最大值)都适用于字符串,但字符串是不可变的,因此所有的元素赋值和切片赋值都是非法的;
>>> website="https://www.baidu.com"
>>> website[-3:]
'com'
>>> website[-3:]="cn"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
字符串方法
字符串方法是从Python1.6到2.0慢慢加进来的,同时它们也被加到了Jython中,字符有很多较为实用的方法,这些方法实现了string模块的大部分方法,如下表所示列出了目前字符串内建支持的方法,所有的方法都包含了对Unicode的支持,有一些甚至是专门用于Unicode的,具体如下;
string.capitalize():把字符串的第一个字符大写;
string.casefold():把字符串的所有字符都变成小写;
string.center(width):返回一个原字符串居中,并使用空格填充至长度 width 的新字符串;
string.count(str, beg=0, end=len(string)):返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数;
string.decode(encoding='UTF-8', errors='strict'):以 encoding 指定的编码格式解码 string,如果出错默认报一个 ValueError 的 异 常 , 除非 errors 指 定 的 是 'ignore' 或 者'replace';
string.encode(encoding='UTF-8', errors='strict'):以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace';
string.endswith(obj, beg=0, end=len(string)):检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False;
string.expandtabs(tabsize=8):把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8;
string.find(str, beg=0, end=len(string)):检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1;
string.format():格式化字符串;
string.index(str, beg=0, end=len(string)):跟find()方法一样,只不过如果str不在 string中会报一个异常;
string.isalnum():如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False;
string.isalpha():如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False;
string.isdecimal():如果 string 只包含十进制数字则返回 True 否则返回 False;
string.isidentifer():判断是否是标识符,如果字符串仅包含字母数字字母(a-z)和(0-9)或下划线(_),则该字符串被视为有效标识符。有效的标识符不能以数字开头或包含任何空格;
string.isdigit():如果 string 只包含数字则返回 True 否则返回 False.;
string.islower():如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False;
string.isspace():是否是空白字符;
string.isnumeric():如果 string 中只包含数字字符,则返回 True,否则返回 False;
string.isspace():如果 string 中只包含空格,则返回 True,否则返回 False.;
string.istitle():如果 string 是标题化的(见 title())则返回 True,否则返回 False;
string.isupper():如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False;
string.join(seq):以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串,需要注意是的join是将可迭代对象一个一个元素迭代出来,和第二个元素拼接;
string.ljust(width,str):返回一个原字符串左对齐,并使用指定字符填充width长度的新字符串,默认空格填充;
string.lower():转换 string 中所有大写字符为小写.;
string.lstrip():截掉 string 左边的空格;
string.maketrans(intab, outtab]):maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。;
max(str):返回字符串 str 中最大的字母。;
min(str):返回字符串 str 中最小的字母。;
string.partition(str):有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把字符串string分成一个3元素的元组(string_pre_str,str,string_post_str),如果string中不包含str 则 string_pre_str == string.;
string.replace(str1, str2, num=string.count(str1)):把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.;
string.rfind(str, beg=0,end=len(string) ):类似于 find() 函数,返回字符串最后一次出现的位置,如果没有匹配项则返回 -1。;
string.rindex( str, beg=0,end=len(string)):类似于 index(),不过是从右边开始.;
string.rjust(width,str):返回一个原字符串右对齐,并使用指定字符填充至width的长度的新字符串,默认空格填充;
string.rpartition(str):类似于 partition()函数,不过是从右边开始查找;
string.rstrip():删除 string 字符串末尾的空格.;
string.split(str="", num=string.count(str)):以 str 为分隔符切片 string,如果 num 有指定值,则仅分隔 num+ 个子字符串;
string.splitlines([keepends]):按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。;
string.startswith(obj, beg=0,end=len(string)):检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查.;
string.strip([obj]):在 string 上执行 lstrip()和 rstrip();
string.swapcase():翻转 string 中的大小写;
string.title():返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle());
string.translate(str, del=""):根据 str 给出的表(包含 256 个字符)转换 string 的字符,要过滤掉的字符放到 del 参数中;
string.upper():转换 string 中的小写字母为大写;
string.zfill(width):返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0;
字符串格式化
将值转换为字符串并设置其格式是一个重要的操作,需要考虑众多不同的需求,因此随着时间的流失,Python提供了多种字符串格式设置方法。以前主要解决方案是使用字符串格式设置运算符——百分号,在%左边指定一个字符串(格式化字符),并在右边指定要设置其格式的值,指定要设置其格式的值时,可使用单个值(如字符串或数字),如果要设置多个值,那么可使用元组,当然,也可以使用字典,但是最常见的是使用元素;
>>> values=("cce",18)
>>> format="my name is %s and my age is %s" %values
>>> print(format)
my name is cce and my age is 18
内置模块字符串格式化
上述格式字符串中的%s称为转换说明符,指出了要将值插入什么地方,s意味着将值视为字符串进行格式设置,如果指定的值不是字符串,需使用str将其转换为字符串,其他说明符,将在下面做出示例,如 %.3f表示将值设置为包含3位小数的浮点数;
可能遇到的另一种的解决方案是所谓的模版字符串,它使用类似于UNIX shell的语法,旨在简化基本的格式设置机制;
包含等号的参数称为关键字参数,在字符串格式设置中可将关键字参数视为一种向命名替换字段提供值的方式;
>>> from string import Template
>>> tmpl=Template("My Name Is $name! and My Age Is $age")
>>> tmpl.substitute(name="cce",age=18)
'My Name Is cce! and My Age Is 18'
有序格式化
编写新代码时,应选择使用字符串方法format,它融合并强化了早期方法的有点,使用这种方法时,每个替换字段都用花括号扩起来,其中可能包含名称,还可能包含有关如何对应的值,并进行转换和格式设置的信息;
>>> print("My Name Is {} and my age is {}".format("cce",18))
My Name Is cce and my age is 18
无序格式化
可以看到,上面通过format的方法,进行字符串格式化它是一一对应的,也就是第一个大扩号对应着format里面的第一个值,它是有序的,其实对于format来讲,它也可以是无序的;
>>> print("My Name Is {1} and my age is {0}".format(18,"cce")) # 索引默认从0开始
My Name Is cce and my age is 18
关键字参数格式化
可以看到,上面是通过元组索引的方式来进行格式化的,其实format一样也支持关键字参数格式化,当然既然是关键字参数,那么就没有有序无序之理了,只要我们传入对应的关键字参数即可;
>>> print("My Name Is {name} and my age is {age}".format(age=18,name="cce"))
My Name Is cce and my age is 18
列表元素格式化
除了以上的方式来进行字符串格式化之外,我们可以通过获取序列指定元素的形式来进行字符串格式化,可使用索引来获取指定序列的指定元素;
>>> fullname=['cce','cfj']
>>> print("cce name is {name[1]}".format(name=fullname))
cce name is cfj
字符串类型格式化
我们还可以具体指定要转换的值是哪种类型,更准确的说,是要将其视为哪种类型,例如,可能提供一个证书,但因为特殊的情况,我们要将其转为小数进行处理,为此,可在格式说明(即冒号后面)使用字符串f(表示浮点数),来进行处理;
>>> print("this box is {money:f} yuan".format(money=18))
this box is 18.000000 yuan
字符串格式类型
可以看到上面,已经做过了基础的类型转换,将证书转换为了小数,那么对于Python里面的字符串格式化来讲,这种类型转换是有很多种的,这样的类型说明符有很多个,具体如下;
b:将整数表示为二进制数;
c:将整数解读为Unicode值;
d:将整数视为十进制数进行处理,这是整数默认使用的说明符;
e:使用科学表示法来表示小数(用e来表示指数);
E:与e相同,但用E来表示指数;
f:将小数表示为定点数;
F:与f相同,但对于特殊值(nan和inf),使用大写表示;
g:自动在定点表示法和科学表示法之间做出选择。这是默认用于小数的说明符;
G:与g相同,但使用大写来表示指数和特殊值;
n:与g相同,但插入随区域而异的数字分隔符;
o:将整数表示为八进制数;
s:保持字符串的格式不变;
x:将整数表示为十六进制数并使用小写字母;
X:与x相同,但使用大写字母;
%:将数表示为百分比值;
宽度
设置浮点数的格式时,默认在小数点后面显示6位小树,并根据需要设置的字段的宽度,而不进行任何形式的填充,当这种默认设置不是想要的时候,可以在这种情况下,根据需要在格式说明中指定宽度,和精度;
宽度是使用整数指定的,需要注意的是,字符串和数字的对齐方式,大不相同,如下;
>>> print("'{num:10}'".format(num=3))
' 3'
>>> print("'{name:10}'".format(name="Python"))
'Python '
精度
精度也是使用整数指定的,但需要在它前面加一个表示小数点但句点;
>>> print("'{num:.2f}'".format(num=3))
'3.00'
宽度和精度
这里显示但指定来类型f,因为默认但精度处理方式稍有不同,当然,也可同时指定宽和精度;
>>> print("'{num:10.2f}'".format(num=3))
' 3.00'
千位分隔符
同时呢,字符串格式化也可实现千位分隔符的方式,来进行大数字分割,一般可使用逗号进行分割,如果同时指定其他格式设置元素时,这个逗号应该放在宽度和表示精度的句点之间;
>>> print("'{num:,}'".format(num=(10*100000)))
'1,000,000'
>>> print("'{num:,.2f}'".format(num=(10*100000)))
'1,000,000.00'
填充
有很多用于设置数字格式的机制,比如便于打印整齐的表格,在大多数情况下,值需指定宽度和精度即可,但包含负数后,原本漂亮的输出可能不再漂亮,另外,字符串和数字的默认对齐方式不同,在一栏中同时包含字符串和数时,在指定宽度和精度的数前面,可添加一个标志,这个标志可以是零、加号、减号或者空格,其中零表示使用0来填充数字;
>>> print("'{num:010,.2f}'".format(num=(10*100)))
'001,000.00'
>>> print("'{num:010}'".format(num=(10*100)))
'0000001000'
对齐
要指定字符串左对齐、右对齐和居中对齐,可分别使用<、>和^;
# 宽度为10,居左
>>> print("'{num:<10}'".format(num=(10*100)))
'1000 '
# 宽度为10,居右
>>> print("'{num:>10}'".format(num=(10*100)))
' 1000'
# 宽度为10,居中
>>> print("'{num:^10}'".format(num=(10*100)))
' 1000 '
# 填充居中
>>> print("'{num:%^10}'".format(num=(10*100)))
'%%%1000%%%'
字符串拼接
print("test""test") # testtest
或
print("test"+"test") # testtest
str和repr
Python打印所有的字符串时,都用引号将其括起来,这是因为Python打印值时,保留其在代码中都样子,而不是你细微看到都样子,但如果使用print结果将不同;
# 直接使用str或者直接print,返回的值是用户易于看懂的值
print('Car') # Car
print(str('Car')) # Car
# repr 打印值,并保留其原来的样子
print(repr('Car')) # 'Car'
原始字符串
原始字符串主要是解决字符串保持原样的问题,在很多情况下,我们都可能会用到转义,如果反斜线,比如\n,如果我们直接使用print打印出一个"\name",那么就会输出一个换行和一个ame,所以此时就是原始字符串发挥作用的时候了;
print('\name') # ame
print(r'\name') # \name
- 注意:
原始字符串不能以单个反斜杠结尾,除非对其进行转义,但是转义时,用于转义的字符串也将是字符串的一部分,如果在特定的场景下需要使用反斜杠结尾可以这样写print(r'\name''\\')