Python学习笔记(2)——数据类型之数字与字符串

数据结构简介

数据结构是以某种方式(例如通过编号)组合起来的数据元素(例如数字,字符)的集合。在Python中,最基本的数据结构就是序列(sequence)。序列中每个元素都有编号,这个编号就是元素的位置或索引,其中第一个元素的索引是0,第二个是1,第三个是2,依此类推。

容器(container)

Python支持一种数据结构的基本概念,名为容器。容器基本上就是可包含其它对象的对象,两种主要的容器是序列(例如列表和元组)和映射(如字典),在序列中,每个元素都有编号,而在映射中,每个元素都有名称(也叫键(key))。有一种既不是序列,也不是映射的容器,叫集合(set)

Python数据类型概览

python3中有六个标准的数据类型,分别为:①Number(数字);②String(字符串);③List(列表);④Tuple(元组);⑤Sets(集合);⑥Dictionary(字典)。

根据能否更改这些类型变量的值,可以把这六个标准类型划分为两类:

第一类:不可变数据(四个):Number(数字)、String(字符串)、Tuple(元组)、Sets(集合);

第二类:可变数据(两个):List(列表)、Dictionary(字典)。

根据不同类型的数据内的元素是否有顺序,还可以划分两类:

第一类:有序序列:列表,元组,字符串;

第二类:无序序列:字典,集合。

变量的赋值

Python中变量要遵循一定的规则,例如不得以数字开头,不得以Python关键字作为变量。此外,Python还提供了一个函数用于判断一个字符串能否作为变量的名称,即isidentifier(),如下所示:

1
2
3
4
>>> 'abc'.isidentifier()
True
>>> '3abc'.isidentifier()
False

常规赋值操作

Python使用等号(=)给变量赋值,等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
biotest@biotest-VirtualBox:~/python3/01basic$ cat variable.py
#!/usr/bin/python3
counter = 100
miles = 1000.00
name = "runoob"
print(counter)
print(miles)
print(name)
biotest@biotest-VirtualBox:~/python3/01basic$ python3 variable.py
100
1000.0
runoob

多变量赋值

Python可以同时对多个变量进行赋值,如下所示:

1
a = b = c =1

或者像这样:

1
a, b, c = 1, 2, "runoob"

这种赋值试方式,就是相当于a = 1, b = 2, c = "runoob"

判断是否是同一个对象——is

两个变量是否指向的是同一个对象,可以用is 运算符,如下所示:

1
2
3
4
5
6
>>> a = 'banana'
>>> b = 'banana'
>>> a is b
True
>>> b is a
True

Number(数字)

类型判断函数type()

Python3中的数字类型具体包括int(整型)float(浮点型)bool(布尔型)complex(复数型)这四种。使用内置的type()函数可以查看对象的类型,如下所示:

1
2
3
4
>>> a, b, c, d = 20, 5.5, True, 4+4j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
>>>

类型判断函数instance()

还可以通过instance函数来判断,这个函数的使用格式为instance(a,b),即判断a是否是b的一个实例,如下所示:

1
2
3
4
5
>>> a = 111
>>> isinstance(a, int)
True
>>> isinstance(a, float)
False

isinstancetype()的区别可以通过一些代码来看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
biotest@biotest-VirtualBox:~/python3/01basic$ cat type_instance_diff.py
#!usr/bin/python3
class A:
pass
class B(A):
pass
print(isinstance(A(),A))
print(type(A()) == A)
print(isinstance(B(),A))
print(type(B()) == A)
biotest@biotest-VirtualBox:~/python3/01basic$ python3 type_instance_diff.py
True
True
True
False

区别就是,type()认为子类与父类不是一个类型,isinstance()认为子类与父类是一个类型。

字符串转换为整型

不同类型的变量有时候会出现错误,如下所示:

1
2
3
4
5
6
>>> num = 1
>>> string = '1'
>>> print(num + string)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

因此,只要在一段代码中要涉及不同类型的变量,最好使用type()函数来查看一下数据类型。如果不同,有时候需要进行类型转换,如下所示:

1
2
3
4
5
>>> num = 1
>>> string = '1'
>>> num2 = int(string)
>>> print(num +num2)
2

变量的删除

变量的删除使用del函数。

字符串

字符串的访问

字符串就是一串有序的字符。你可以通过方括号操作符,每次去访问字符串中的一个字符,如下所示:

1
2
3
4
>>> fruit = 'banana'
>>> letter = fruit[1]
>>> letter
'a'

其中[1]是索引,用于指示字符串中字符的位置,python中第1个位置是[0],而非[1]。

字符串的长度

len是一个内置函数,会返回一个字符串中字符的长度:

1
2
3
4
5
6
>>> len(fruit)
6
>>> len(letter)
1
>>> fruit[len(fruit)-1] #返回fruit的最后一个字母
'a'

长字符串加三引号'''

如果要在Python中输入比较长的字符串,例如要跨越多行的字符串,可以使用三引号''',如下所示:

1
2
3
4
5
print('''This is a very long string. It continues here.
And it's not over yet. "Hello, world!
Still here.''')print('''This is a very long string. It continues here.
And it's not over yet. "Hello, world!
Still here.''')

运行结果如下所示:

1
2
3
This is a very long string. It continues here.
And it's not over yet. "Hello, world!
Still here.

换行加左斜杠\

常规字符串如果要换行,需要加左斜杠\,左斜杠和换行符将被转义,即被忽略,如下所示:

1
2
print \
("Hello, python")

运行结果如下所示:

1
Hello, python

字符串的加法+

字符串的加法就是将字符串连接起来,如下所示:

1
2
3
4
5
6
>>> what_he_does = ' plays '
>>> his_instrument = 'guitar'
>>> his_name = 'Robert Johnson'
>>> artist_intro = his_name + what_he_does + his_instrument
>>> print(artist_intro)
Robert Johnson plays guitar

字符串无法修改

字符串属于不可变序列,无法进行修改,如下所示:

1
2
3
4
5
>>> greeting = 'Hello, world!'
>>> greeting[0] = 'J'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

但是可以新建一个字符串,如下所示:

1
2
3
4
>>> greeting = 'Hello, world!'
>>> new_greeting = 'J' + greeting[1:]
>>> print(new_greeting)
Jello, world!

在Python中处理这类无法修改的数据类型时,通常的做法就是提取相应的字符串,然后再新建一个。

字符串的切片与索引

先看一个案例,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> name = 'My name is Mike'
>>> print(name[0]) # 切下第0个元素
M
>>> print(name[-4]) # 切下倒数第4个元素
M
>>> print(name[11:14]) # 切下第11到第14个元素,左闭右开区间
Mik
>>> print(name[11:15]) # 切下第11到第15个元素,左闭右开区间
Mike
>>> print(name[5:]) # 从第5个元素开始切,一直到结尾
me is Mike
>>> print(name[:5]) # 从第0个元素开始切,不包括第5个元素,左闭右开区间
My na

再看另外一个案例,下面的这个案例中使用了几个参数,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>> b = 'ACTGCATCATC'
>>> b[0:3] # 截取0到3元素
'ACT'
>>> b[2:4] # 截取2到4元素
'TG'
>>> b[2:-1] # 截取第2到最后一个元素
'TGCATCAT'
>>> b[2:] # 截取第2到最后一个元素
'TGCATCATC'
>>> b[::-1] # #创造一个与原字符串顺序相反的字符串
'CTACTACGTCA'
>>> b[-3:-1] #截取倒数第三位与倒数第一位之前的字符
'AT'
>>> b[-3:] #截取倒数第三位到结尾
'ATC'
>>> b[:-5:-3] #逆序截取
'CC'
>>> b[::2] # 隔一个取一个元素的操作
'ATCTAC'
>>> b[0:6:2] # 截取第0到第6个元素,然后再间隔1个取元素
'ATC'
>>> b[9:0:-3] # 截取第0到第9个元素,然后倒序间隔取3个元素
'TTG'
>>>

步长

看一个案例,如下所示:

1
2
3
test = "0123456789"
test
test[0:7:2]

运行结果如下所示:

1
0246

这里面涉及到一个步长的概念,上面代码表示的是意思是,取0到7之间的元素,第0个元素是0,第7个元素是7(但末尾元素不取),并间隔取,其中[0:7:2]这个2就表示间隔取。如果是3,则是间隔3个取,如下所示:

1
2
test[0:7:3]
036

字符串的分割split()

这里要与字符串的切片区分,字符串的分割使用的是split(),如下所示:

1
2
3
4
>>> s = 'pining for the fjords'
>>> t = s.split()
>>> t
['pining', 'for', 'the', 'fjords']

可选的参数是定界符,是用来确定单词边界的。下面这个例子中就是把连接号-作为定界符:

1
2
3
4
5
>>> s = 'spam-spam-spam'
>>> delimiter = '-'
>>> t = s.split(delimiter)
>>> t
['spam', 'spam', 'spam']

字符串的拼接join()

join是与split功能相反的一个方法。它接收一个字符串列表,然后把所有元素拼接到一起。join是一个字符串方法,所以必须把 join放到定界符后面来调用,并且传递一个列表作为参数:

1
2
3
4
5
>>> t = ['pining','for','the','fjords']
>>> delimiter = ' '
>>> s = delimiter.join(t)
>>> s
'pining for the fjords'

替换某字符串replace()

这里用到了字符串的replace()方法,这个方法是用某个字符替换某个字符,虽然是替换,但是原字符是不变的,只是将替换后的字符赋值给了一个新的变量,如下所示:

1
2
3
4
>>> phone_number = '1386-666-0006'
>>> hiding_number = phone_number.replace(phone_number[:9],'*'*9)
>>> print(hiding_number)
*********0006

替换某字符串translate()

方法translatereplace一样能替换字符串的特定部分,但不同的是,translte只能进行单字符替换,它的优势在能够同时替换多个字符,效率比replace高。

现在看一个案例,将某段字符中的cs分别替换为kz

在转换之前,translate需要创建一个转换表,这个转换表指出了不同Unicode码点之间的转换关系,要创建转换表,可以对字符串类型str调用方法maketrans,这个方法接收2个参数:两个长度相同的字符串,它们指定要将第一个字符串中的每个字符都替换为第二个字符串中相应的字符,类似于以下的东西:

1
table = str.maketrans('cs', 'kz')

完整代码为:

1
2
3
4
5
table = str.maketrans('cs', 'kz')
table
test_string = 'this is an incredibel test'
test_string.translate(table)
test_string

运行结果如下所示:

1
2
3
4
5
6
>>> table = str.maketrans('cs', 'kz')
>>> table
{99: 107, 115: 122}
>>> test_string = 'this is an incredibel test'
>>> test_string.translate(table)
'thiz iz an inkredibel tezt'

其中>>> table {99: 107, 115: 122}这一部分表示Unicode码点之间的映射。

在调用maketrans时,还可以添加第3个参数,它是指定哪些字符删除,例如下面的代码会将空格删除,如下所示:

1
2
3
table = str.maketrans('cs', 'kz',' ') #第三个参数是一个空格
test_string = 'this is an incredibel test'
test_string.translate(table)

运行结果如下所示:

1
2
3
4
>>> table = str.maketrans('cs', 'kz',' ') #第三个参数是一个空格
>>> test_string = 'this is an incredibel test'
>>> test_string.translate(table)
'thizizaninkredibeltezt'

字符串计数

下面的这段代码是统计在banana这个单词有多少个a,如下所示:

1
2
3
4
5
6
7
8
>>> word = "banana"
>>> count = 0
>>> for letter in word:
... if letter == 'a':
... count = count + 1
...
>>> print(count)
3

除了函数形式外,还可以使用count()方法,如下所示:

1
2
3
>>> word = "banana"
>>> word.count('a')
3

查询字符串find()rfind()index()

查询字符常用的方法是find()rfind()index()。其中,find()rfind()的区别在于,一个是在左边开始查找,一个在右边开始查找(r就是right的意思),index()法检测字符串中是否包含子字符串str,如果指定beg(开始) 和end(结束) 范围,则检查是否包含在指定范围内,该方法与 python find()方法一样,只不过如果str不在 string中会报一个异常。find()rfind()查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次出现的位置,如果不存在,返回-1,存在返回1,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> s = 'apple, peach, banana, peach, pear'
>>> s.find("peach")
7
>>> s = 'apple, peach, banana, peach, pear'
>>> s.find("peach") # 返回第一次出现的位置
7
>>> s.find("peach",7) # 在指定位置开始查找
7
>>> s.find("peach",7,20) # 在指定范围内进行查找
7
>>> s.rfind('p') # 从字符串尾部向前查找
29
>>> s.index('p') # 返回首次出现的位置
1
>>> s.index('pe')
7
>>> s.index('pear')
29
>>> s.index('ppp') # 指定子字符串不存在时抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found

再看一个查询电话号码的案例:

1
2
3
4
5
6
7
>>> search = '168'
>>> num_a = '1386-168-0006'
>>> num_b = '1681-222-0006'
>>> print(search + ' is at ' + str(num_a.find(search)) + ' to '+str(num_a.find(search) + len(search)) + ' of num_a')
168 is at 5 to 8 of num_a
>>> print(search + ' is at ' + str(num_b.find(search)) + ' to '+str(num_b.find(search) + len(search)) + ' of num_b')
168 is at 0 to 3 of num_b

查询某字母

方法与前面的类似,如下所示:

1
2
3
4
>>> word = 'banana'
>>> index = word.find('a')
>>> print(index)
1

in运算

in 这个词在字符串操作中是一个布尔操作符,它读取两个字符串,如果前者的字符串为后者所包含,就返回真,否则为假:

1
2
3
4
>>> 'a' in 'banana'
True
>>> 'seed' in 'banana'
False

删除字符串中的空格strip()

使用的strip()方法,如下所示:

1
2
3
4
5
6
7
>>> mybag = [' glass',' apple','green leaf ']
>>> #有的前面有空格,有的后面有空格
... print([one.strip() for one in mybag])
['glass', 'apple', 'green leaf']
>>> #去掉元素前后的空格
... ['glass', 'apple', 'green leaf']
['glass', 'apple', 'green leaf']

遍历所有字符串

使用的是for循环,第一种方法,使用索引,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> index = 0
>>> fruit = "banana"
>>>
>>> while index < len(fruit):
... letter = fruit[index]
... print(letter)
... index = index +1
...
b
a
n
a
n
a

第二种方法,直接使用字符串,如下所示:

1
2
3
4
5
6
7
8
9
10
>>> fruit = "banana"
>>> for letter in fruit:
... print(letter)
...
b
a
n
a
n
a

字符串的复制

直接使用乘法就行,如下所示:

1
2
3
4
>>> words = 'word'*4
>>> print(words)
wordwordwordword
wordwordwordword

字符串的 大小转换upper()lower(),首字母大写capitalize()title()capwords()

符串提供了一些方法,这些方法能够进行很多有用的操作。方法和函数有些类似,也接收参数然后返回一个值,但语法稍微不同。比如,upper这个方法就读取一个字符串,返回一个全部为大写字母的新字符串。与函数的upper(word)语法不同,方法的语法是word.upper()。后面括号里面是空白的,表示这个方法不接收参数,如下所示:

1
2
3
4
>>> word = 'banana'
>>> new_word = word.upper()
>>> print(new_word)
BANANA

upper()方法是大写,lower()是小写,capitalize()首字母大写、title()将每个字母变为大写,swapcase()大小写互换,如下所示:

1
2
3
4
5
6
7
8
9
>>> s = "What is Your Name?"
>>> s.lower()
'what is your name?'
>>> s.upper()
'WHAT IS YOUR NAME?'
>>> s.capitalize()
'What is your name?'
>>> s.swapcase()
'wHAT IS yOUR nAME?'

另外两个词首大写的方法是tilte()string模块中的capwords()函数,如下所示:

1
2
3
4
5
test_1 = "that's all folks"
test_1.title()
import string
string.capwords(test_1)

运行结果如下所示:

1
2
3
4
5
6
7
>>> test_1 = "that's all folks"
>>> test_1.title()
"That'S All Folks"
>>>
>>> import string
>>> string.capwords(test_1)
"That's All Folks"

ASCII值的转换

ord()是一个内建函数,能够返回某个字符(注意,是一个字符,而不是多个字符组成的串),所对应的ASCII值(是十进制的),字符a在ASCII中的值是97,空格在ASCII中也有值,是32,反过来,根据整数值得到的相应字符,可以使用chr(),如下所示:

1
2
3
4
5
6
>>> print(ord('a'))
97
>>> print(chr(97))
a
>>> print(chr(98))
b

转义字符

转义字符是指,在字符串中某些特定的符号前加一个斜线之后该字符将被解释为另外一种含义,不再表示本来的字符,常见的转义字符如下所示:

转义字符 含义
\b 退格,把光标移动到前一列位置
\f 换页符
\n 换行符
\r 回车
\t 水平制表符
\v 垂直制表符
\\ 一个\
\' 单引号
\" 双引号
\ooo 3位八制对应的字符
\xhh 2位十六进制对应的字符
\uhhhh 4位十六进制数表示的Unicode字符

使用案例如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> print('Hello\nWorld')
Hello
World
>>> oct(65)
'0o101'
>>> print('\101') # 3位八进制数对应的字符
A
>>> hex(65)
'0x41'
>>> print('\x41') # 2位十六进制数对应的字符
A
>>> ord('张')
24352
>>> hex(_)
'0x5f20'
>>> print('\u8463') # 4位十六进制数表示的Unicode字符

eval函数

eval()是一具内置变数,它可以将任意字符串转化为Python表达式,并进行求值。

1
2
3
4
5
6
7
>>> eval("3+4") # 计算表达式的值
7
>>> a = 3
>>> b = 5
>>> eval('a+b') # 这时候要求变量a和b都已经存在
8
>>>

判断某字符串的开头或结尾

startswith(),endswith()用于判断字符串是否以指定字符串开始或结束,可以接收两个整数参数来限定字符串的检测范围,如下所示:

1
2
3
4
5
6
7
8
>>> s = 'Beautiful is better than ugly'
>>> s.startswith('Be') # 检测整个字符串
True
>>> s.startswith('Be',5) # 指定检测范围的起始位置
False
>>> s.startswith('Be',0,5) # 指定检测范围的起始和结束位置
True
>>>

判断字符串的首个字符内容

isalnum(),isalpha(),isdigit(),isdecimal(),isnumeric(),isspace(),isupper(),islower()用于检测字符串是否为数字或字母,是否为字母,是否为数字字符,是否为空白字符,是否为大写字母以及是否为小写字母,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> '1234abcd'.isalnum()
True
>>> '1234abcd'.isalpha() # 全部为英文字母时返回True
False
>>> '1234abcd'.isdigit() # 全部为数字时返回True
False
>>> 'abcd'.isalpha()
True
>>> '1234.0'.isdigit()
False
>>> '1234'.isdigit()
True
>>> '九'.isnumeric() # isnumeric()方法支持汉字数字
True
>>> '99'.isnumeric()
True
>>> '九'.isdigit()
False
>>> '九'.isdecimal()
False

添加填充字符center

字符串的方法center的功能在于向字符串两边填充字符,默认是空格,如下所示:

1
2
3
4
string_test = "The Middley by Jimmy Eat world"
string_test
string_test.center(39)
string_test.center(39,"*")

运行结果如下所示:

1
2
3
4
5
6
7
>>> string_test = "The Middley by Jimmy Eat world"
>>> string_test
'The Middley by Jimmy Eat world'
>>> string_test.center(39)
' The Middley by Jimmy Eat world '
>>> string_test.center(39,"*")
'*****The Middley by Jimmy Eat world****'

其中数字39表示,填充后的字符串一共39个字符。

输出格式美化format()

Python两种输出值的方式:表达式语句和print()函数。 第三种方式是使用文件对象的write()方法,标准输出文件可以用sys.stdout引用,write()方法在处理文本文件的时候经常使用,如果你希望输出的形式更加多样,可以使用str.format()函数来格式化输出值,如果希望将输出的值转成字符串,可以使用repr()str()函数来实现。 这两个函数区别如下所示:

  1. str():函数返回一个用户易读的表达形式。
  2. repr():产生一个解释器易读的表达形式。

输出格式案例1-字符串

如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> str(s)
'Hello Runoob'
>>> print(type(str(s)))
<class 'str'>
>>> print(type(s))
<class 'str'>
>>> repr(s)
"'Hello Runoob'"
>>> print(type(repr(s)))
<class 'str'>
>>> str(1/7)
'0.14285714285714285'
>>> x = 10*3.25
>>> y=200*200
>>> s = 'The value of x is: ' + repr(x) + ',the value of y is: ' + repr(y) + '...'
>>> print(s)
The value of x is: 32.5,the value of y is: 40000...
>>> hello = 'hello, runoob\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, runoob\n'
>>> repr((x,y,('Google', 'Runoob')))
"(32.5, 40000, ('Google', 'Runoob'))"

输出格式案例2-整数输出

下面的代码输出一个平方与立方根,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> for x in range(1,5):
... print(repr(x).rjust(2),repr(x*x).rjust(3),end=' ')
# 使用print添加空格,即end=' '
# rjust()表示字符串靠右,并在左边填充空格
... print(repr(x*x*x).rjust(4))
...
1 1 1
2 4 8
3 9 27
4 16 64
>>> for x in range(1,5):
... print('{0:2d} {1:3d}{2:4d}'.format(x,x*x,x*x*x))
...
1 1 1
2 4 8
3 9 27
4 16 64

输出格式案例3zfill()

zfill方法表示在数字的左边填充0,如下所示:

1
2
3
4
5
6
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

数值输出的格式化

字符串的格式化输出有两种方式,一种是使用%符号,这个符号为称转换说明符,它可以指出要将值插入什么地方,例如%s的意思表示对字符串进行格式设置,如果指定的值不是字符串,那么就转换为字符串,再例如%.3f则是将格式设计为包含3位小数点的浮点数。

另外一种是使用str.format(),下面是使用的一些案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
>>> print("{:,}".format(123456))
#输出1234,56
123,456
>>> print("{a:w^8}".format(a="8"))
#输出www8wwww
www8wwww
>>> print("%.5f" %5)
#输出5.000000
5.00000
>>> print("%-7s3" %("python"))
#输出python 3
python 3
>>> print("%.3e" %2016)
#输出2.016e+03,也可以写大E
2.016e+03
>>> print("%d %s" %(123456,"myblog"))
#输出123456 myblog
123456 myblog
>>> print("%(what)s is %(year)d" % {"what":"this year","year":2016})
#输出this year is 2016
this year is 2016
>>> print("{0}{1}".format("hello","fun"))
#输出hellofun,这与CSharp的格式化字符(占位符)相似
hellofun
>>> print("{}{}{}".format("spkk",".","cn"))
#输出spkk.cn
spkk.cn
>>> print("{a[0]}{a[1]}{a[2]}".format(a=["spkk",".","cn"]))
#输出spkk.cn
spkk.cn
>>> print("{dict[host]}{dict[dot]}{dict[domain]}".format(dict={"host":"www","domain":"spkk.cn","dot":"."}))
#输出www.spkk.cn
www.spkk.cn
>>> print("{a}{b}".format(a="python",b="3"))
#输出python3
python3
>>> print("{who} {doing} {0}".format("python",doing="like",who="I"))
#输出I like python
I like python
>>> x = 4
>>> y = 5
>>> z = x +y
>>> print("计算结果是 {0:d}.".format(z))
计算结果是 9.
# 这里的{0:d}表示:0是指format()方法中变量的第一个参数,这里是z,也就是说0指向z,d表示,将z这个变量输出为整数格式。

format()的多参输出

format()也可以用于多参数输出,如下所示:

1
2
3
4
5
6
7
8
9
10
print("Output #1: I'm excited ot learn Python")
x = 4
y = 5
z = x + y
print("Output #2: Four plus five equels{0:d}".format(z))
a = [1, 2, 3, 4]
b = ["first", "second", "third", "fourth"]
c = a + b
print("Output #3: {0}, {1}, {2}".format(a, b, c))

计算结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> print("Output #1: I'm excited ot learn Python")
Output #1: I'm excited ot learn Python
>>> x = 4
>>> y = 5
>>> z = x + y
>>> print("Output #2: Four plus five equels{0:d}".format(z))
Output #2: Four plus five equels9
>>>
... a = [1, 2, 3, 4]
>>> b = ["first", "second", "third", "fourth"]
>>> c = a + b
>>> print("Output #3: {0}, {1}, {2}".format(a, b, c))
Output #3: [1, 2, 3, 4], ['first', 'second', 'third', 'fourth'], [1, 2, 3, 4, 'first', 'second', 'third', 'fourth']

str.format

str.format的基本使用如下所示:

1
2
>>> print('{} website: "{}!"'.format('Runobb tuorial','www.runoob.com'))
Runobb tuorial website: "www.runoob.com!"

括号及其里面的字符(称作格式化字段)将会被format()中的参数替换。在括号中的数字用于指向传入对象在format()中的位置,如下所示:

1
2
3
4
5
>>> print('{0} and {1}'.format('Google','Runoob'))
Google and Runoob
>>>
>>> print('{1} and {0}'.format('Google','Runoob'))
Runoob and Google

如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数,如下所示:

1
2
>>> print('{name}website:{site}'.format(name='Runoob tutorial ',site='www.runoob.com'))
Runoob tutorial website:www.runoob.com

位置及关键字参数可以任意的结合:

1
2
>>> print('Website list {0},{1}, and {other}. '.format('Google','Runoob',other='Taobao'))
Website list Google,Runoob, and Taobao.

'!a'(使用ascii()),'!s'(使用str())和'!r'(使用repr())可以用于在格式化某个值之前对其进行转化,如下所示:

1
2
3
4
5
>>> import math
>>> print('Constant of PI is around:{}.'.format(math.pi))
Constant of PI is around:3.141592653589793.
>>> print('Constant of PI is around:{!r}.'.format(math.pi))
Constant of PI is around:3.141592653589793.

可选项':'和格式标识符可以跟着字段名。这就允许对值进行更好的格式化。下面的例子将Pi保留到小数点后三位,如下所示:

1
2
3
>>> import math
>>> print('Constant PI is about: {0:.3f}.'.format(math.pi))
Constant PI is about: 3.142.

':'后传入一个整数,可以保证该域至少有这么多的宽度。用于美化表格时很有用,如下所示:

1
2
3
4
5
6
7
>>> table = {'Google':1,'Runoob':2,'Taobao':3}
>>> for name, number in table.items():
... print('{0:10} ==> {1:10d}'.format(name,number))
...
Google ==> 1
Runoob ==> 2
Taobao ==> 3

如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。 最简单的就是传入一个字典, 然后使用方括号[]来访问键值 :

1
2
3
>>> table = {'Google':1,'Runoob':2,'Taobao':3}
>>> print('Runoob:{0[Runoob]:d}; Google:{0[Google]:d}; Taobao:{0[Taobao]:d}'.format(table))
Runoob:2; Google:1; Taobao:3

也可以通过在 table 变量前使用**来实现相同的功能:

1
2
3
>>> table = {'Google':1,'Runoob':2,'Taobao':3}
>>> print('Runoob:{Runoob:d};Google:{Google:d};Taobao:{Taobao:d}'.format(**table))
Runoob:2;Google:1;Taobao:3

%用于格式化输出

格式化字符串时,Python使用一个字符串作为模板。模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式。Python用一个tuple将多个值传递给模板,每个值对应一个格式符。%的格式化输出如下所示:

1
2
>>> print("I'm %s. I'm %d year old" % ('Vamei', 99))
I'm Vamei. I'm 99 year old

格式符汇总

格式符为真实值预留位置,并控制显示的格式。格式符可以包含有一个类型码,用以控制显示的类型,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)

格式符号进阶

格式符号还可以按如下方式进行使用:

1
2
3
4
5
1. %[(name)][flags][width].[precision]typecode
2. (name)为命名
3. flags可以有+,-,' '0。+表示右对齐。-表示左对齐。' '为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填充。
4. width表示显示宽度
5. precision表示小数点后精度

使用案例如下所示:

1
2
3
4
5
6
>>> print("%+10x" % 10)
+a
>>> print("%04d" % 5)
0005
>>> print("%6.3f" % 2.3)
2.300

上面的width, precision为两个整数。我们可以利用*,来动态代入这两个量。比如:

1
2
>>> print("%.*f" % (4, 1.2))
1.2000

Python实际上用4来替换*。所以实际的模板为%.4f:

1
2
>>> print("%.4f" % (1.2))
1.2000

参考资料

  1. 编程小白的第一本Python入门书
  2. Python可以这样学.董付国
  3. Python教程|菜鸟教程
  4. MagnusLieHetland. Python基础教程.第3版[M]. 人民邮电出版社, 2018.
  5. Python数据分析基础。ClintonW.Brownley.