Python基础·数据类型

输入与输出

print()

Python使用print()函数来输出信息,例如print('Samuel AK IOI')会输出Samuel AK IOI

print()函数接受多个参数,每个参数之间默认会以空格隔开:

1
2
>>> print('Today', 'is', 'Saturday')
Today is Saturday

如果不想要默认的空格,可以通过修改sep参数来实现参数间的分隔内容:

1
2
>>> print('Luckyfuy', 'Summer_Light', 'Yummy', 'FZYFZY', sep='|---|')
Luckyfuy|---|Summer_Light|---|Yummy|---|FZYFZY

同时,print()函数在末尾会自动输出一个换行符\n,因此,我们可以通过修改end参数来修改末尾输出的内容:

1
2
3
4
5
>>> print('Are you OK?'); print('Are you OK?')
Are you OK?
Are you OK?
>>> print('Are you OK?', end=' '); print('Are you OK?')
Are you OK? Are you OK?

在上面的例子中我们用到了分号;
;可以用于分隔多个Python语句,达到在一行中运行多句代码的作用。

input()

输入是通过函数input()来实现的。input()会返回用户输入的内容,其类型为字符串。input()有一个可选参数,用于输出提示信息。
例如:

1
2
3
4
5
6
>>> print(input())
kkksc03
kkksc03
>>> print('Hello', input('Enter your name: '))
Enter your name: Luckyfuy
Hello Luckyfuy

注释

编译时,编译器会自动跳过注释。因此,注释不是给机器看的,而是给人看的。在代码中写上注释是一个良好的习惯,这样一来自己看得懂,其他人也能明白你的意图。
Python中的注释不是和大多数语言一样,使用///**/的。在Python中,#号表示单行注释,三引号'''"""表示多行注释。
例如:

1
2
3
4
5
6
7
8
9
10
11
# 这是一段注释
'''
Python编译器会跳过这一大段文字
直接去运行下面的代码
'''
print('kkksc03 is stupid') # 这段代码会被执行
# 而下面这段代码则不会被执行
# print('Samuel AK IOI')
"""
233
"""

数据类型

Python中有六个标准数据类型:

  • 数字(Number)
  • 字符串(String)
  • 列表(List)
  • 元组(Tuple)
  • 集合(Set)
  • 字典(Dictionary)

其中:

  • 不可变数据:数字(Number)、字符串(String)、元组(Tuple)
  • 可变数据:列表(List)、集合(Set)、字典(Dictionary)

数字(Number)

存在三种不同的数字类型:整数浮点数复数。其中,布尔值是整数的子类型。

数字是由字面值或内置函数与运算符的结果来创建的。不带修饰的整数字面值(包括二进制、八进制和十六进制数)会生成整数;包含小数点或幂运算符的会生成浮点数;在数字字面值末尾加上jJ会生成虚数(实部为零的复数),你可以将其与整数或浮点数相加来得到具有实部和虚部的复数。

type()函数可以用于查询变量所指的数据类型:

1
2
3
>>> a, b, c, d = 233, 123.321, False, 5+6j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>

此外,isinstance()也可以判断变量是否为指定类型:

1
2
3
4
>>> isinstance(a, int)
True
>>> isinstance(d, float)
False

Python完全支持混合算术:当一个二元运算符用于不同数字类型的操作数时,具有“较窄”类型的操作数会被扩展为另一个操作数的类型——整数比浮点数更窄,浮点数又比复数更窄。混合类型数字之间的比较也使用相同的规则。构造器int()float()complex()可被用于生成特定类型的数字。

所有数字类型都支持下列运算,按优先级升序排序(所有数字运算的优先级都高于比较运算):

运算 结果
x + y xy的和
x - y xy的差
x * y xy的积
x / y xy的商
x // y xy的商取整后的结果
x % y xy取模
-x x的相反数
+x x不变
round(x[, n]) x四舍五入到小数点后n位。n默认为$0$
abs(x) x的绝对值
int(x) x转换为整数
float(x) x转换为浮点数
complex(re[, im]) 一个带有实部re和虚部im的复数。im默认为$0$
c.conjugate() 复数c的共轭
divmod(x, y) (x // y, x % y)
pow(x, y[, z]) xy次幂(对z取模)
x ** y xy次幂

注:Python把pow(0, 0)0 ** 0定义为1

一个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> 1 + 1
2
>>> 5 / 3
1.6666666666666667
>>> 5 // 3
1
>>> 5 % 3
2
>>> round(3.1415926, 3)
3.142
>>> abs(-0.3)
0.3
>>> complex(5, -5.5)
(5-5.5j)
>>> divmod(4, 3)
(1, 1)
>>> 2 ** 31 - 1
2147483647

更多数学运算会在mathcmath模块中提到。

整数(Int)

整数具有无限的精度。

前缀0b0o0x分别可以表示二进制数、八进制数和十六进制数:

1
2
3
4
5
6
>>> 0b11011111101010010
114514
>>> 0o337522
114514
>>> 0x1bf52
114514

整数可以进行位运算。二进制按位运算的优先级全都低于数字运算,但又高于比较运算;一元运算~具有与其他一元算术运算(+-)相同的优先级。
此表格是以优先级升序排序的按位运算列表:

运算 结果
x | y xy按位
x ^ y xy按位异或
x & y xy按位
x << n x左移n位,等价于不带溢出检测地乘以pow(2, n)
x << n x右移n位,等价于不带溢出检测地除以pow(2, n)
~x x逐位取反

注:负的移位数会引发ValueError

布尔值(Bool)

布尔值包括两个值:真值True假值False
TrueFalse也可以被视为10进行数学运算,但不建议这样使用。

以下内置对象被视为假值:

  • 被定义为假值的常量:NoneFalse
  • 任何数值类型的零:00.00j
  • 空的序列和多项集:''()[]{}set()range(0)

其余均视为真值。

布尔运算有三种:andornot,分别对应与、或、非。
以下布尔运算按优先级升序排列:

运算 结果
x or y xy中有一项为真,返回真。只有在x为假值时才会对y求值
x and y xy都为真,返回真。只有在x为真值时才会对y求值
not x x为假,返回真

Python中有八种比较运算符,它们优先级相同,但比布尔运算的优先级高。
比较运算符可以任意串联,例如,x < y <= z等价于x < y and y <= z,前者的不同之处在于y只会被求值一次,但在两种情况中当x < y的结果为假值时z都不会被求值。

运算 含义
< 严格小于
<= 小于或等于
> 严格大于
>= 大于或等于
== 等于
!= 不等于
is 对象标识
is not 否定的对象标识

除了不同数字类型外,不同类型比较必定不相等。
当两个对象无法被比较时,会引发TypeError。(例如比较复数与另一个内置数字类型)

isis not用于检测对象的标识号,当且仅当xy是同一对象时x is y返回真,is not则相反。
这两种运算无法自定义,且可以应用于任意两个对象之间并不引发异常。

另外还有innot in两种具有相同优先级的运算,它们用于成员检测。若xs的成员,则x in s返回真,not in与其相反。
对于字符串和字节串类型来说,当且仅当xy的子串时x in yTrue,它等价于y.find(x) != -1。空字符串''是所有字符串的子串。

浮点数(Float)

浮点数即小数,例如3.1478.06-32.5等。
浮点数也可以用科学计数法表示,如$1.23 \times 10^{5}$可以用1.23e5表示,$4 \times 10^{-8}$可以用4e-8表示。

复数(Complex)

复数包含实部和虚部,各用一个浮点数来表示。
一个复数c的实部和虚部可以分别用c.realc.imag表示。

字符串(String)

Python中使用str对象即字符串来处理文本。
字符串字面值有以下三种表示方法:

  • 单引号''允许包含"双"引号'
  • 双引号""允许包含'单'引号"
  • 三重引号:'''三重单引号'''"""三重双引号"""

其中三重引号内允许换行,如以下字符串

1
2
3
4
'''wa
WA
Wa
wA'''

内所有字符都包含在该字符串字面值当中,包括空白字符。

如果不想让换行包含在三重引号中,可以在行尾添加一个\

1
2
3
4
5
6
>>> print('''wa\
... WA
... Wa\
... wA''')
waWA
WawA

如果要表示同种引号,可以使用转义字符\

1
2
>>> 'I\'m OK'
"I'm OK"

很多字符都需要\进行转义,如\n换行、\t制表符等,\本身也需要转义:

1
2
3
4
5
6
7
>>> print('A\nB')
A
B
>>> print('A\tB')
A B
>>> print('A\\B')
A\B

如果字符串中有很多需要转义的字符,可以通过字符串前缀r来禁用字符串内的转义:

1
2
3
4
5
>>> print('\\\n\\')
\
\
>>> print(r'\\\n\\')
\\\n\\

str(object)函数可以把object转化为字符串,如果object为空,那么会返回空字符串''

1
2
3
4
5
6
7
8
>>> str(1)
'1'
>>> str(True)
'True'
>>> str(5e-3j)
'0.005j'
>>> str()
''

字符串格式化类似于C,使用%运算符。
字符串中%后接转换类型,而在字符串后须跟一个%以及与字符串中的%等数量的值。
例如:

1
2
3
4
>>> 'I saw %d birds.' % 7
'I saw 7 birds.'
>>> 'I saw %d birds and %d dogs.' % (10, 2)
'I saw 10 birds and 2 dogs.'

常用的转换类型有:

转换类型 含义
d 十进制整数
o 八进制整数
x 十六进制整数
f 浮点数
e 浮点数指数形式
s 字符串

如果要表示%这个字符本身,可以使用%%

此外,我们还可以指定补齐或补零的位数以及浮点数的精度:

1
2
3
4
5
6
7
8
>>> '%03d' % 5
'005'
>>> '%3d' % 5
' 5'
>>> '%-3d' % 5
'5 '
>>> '%.3f' % 3.1415926
'3.142'

字符串的format()方法也可以格式化字符串,它会用传入的参数依次替换字符串内的占位符{0}{1}等等:

1
2
>>> 'The area of a circle with radius {0} is {1:.2f}.'.format(3, 3.14 * 3 ** 2)
'The area of a circle with radius 3 is 28.26.'

使用以f开头的字符串也是一种格式化字符串的方法,它会用对应的变量替换字符串内的占位符:

1
2
3
4
>>> r = 3
>>> s = 3.14 * r ** 2
>>> f'The area of a circle with radius {r} is {s:.2f}.'
'The area of a circle with radius 3 is 28.26.'

字符串可以用+连接到一起,也可以用*进行重复:

1
2
3
4
>>> 'a' + 'b' + 'c'
'abc'
>>> 'a' * 3
'aaa'

相邻的多个字符串字面值(变量不行!)会自动连接在一起:

1
2
>>> 'a' 'b'
'ab'

字符串可以用下标访问,第一个字符的下标是0

1
2
3
4
>>> 'Hello, World!'[0]
'H'
>>> 'Hello, World!'[5]
','

下标也可以用负数,表示倒数:

1
2
3
4
>>> 'Hello, World!'[-1]
'!'
>>> 'Hello, World!'[-3]
'l'

注意,因为-0等同于0,所以负数下标从-1开始。

字符串还支持切片,取子字符串。[a:b]表示取下标范围在$[a, b)$的字符串:

1
2
3
4
>>> 'Hello, World!'[0:5]
'Hello'
>>> 'Hello, World!'[-6:-1]
'World'

省略第一个下标默认为0,省略第二个下标默认到字符串结束:

1
2
3
4
5
6
>>> 'Hello, World!'[:5]
'Hello'
>>> 'Hello, World!'[-6:]
'World!'
>>> 'Hello, World!'[:]
'Hello, World!'

还可以传入第三个下标[a:b:c],表示每隔c个取一个,负数表示倒着取:

1
2
3
4
5
6
>>> 'Hello, World!'[2:9:2]
'lo o'
>>> 'Hello, World!'[::5]
'H,l'
>>> 'Hello, World!'[::-1]
'!dlroW ,olleH'

内建函数len()返回字符串的长度:

1
2
>>> len('Hello, World!')
13

str()把对象转换为字符串:

1
2
>>> str(114514)
'114514'

列表(List)

列表是一种有序的集合,可以包含不同类型的元素。

1
2
3
>>> l = [114514, 'yes', 3.14, False]
>>> l
[114514, 'yes', 3.14, False]

列表和字符串一样,支持下标和切片:

1
2
3
4
>>> l[0]
114514
>>> l[1:3]
['yes', 3.14]

列表同样支持拼接和重复的操作:

1
2
3
4
>>> l + ['right']
[114514, 'yes', 3.14, False, 'right']
>>> l * 2
[114514, 'yes', 3.14, False, 114514, 'yes', 3.14, False]

len()返回列表的长度:

1
2
>>> len(l)
4

与字符串不同,列表是可变数据,内容可以被改变:

1
2
3
4
5
6
7
8
>>> l
[114514, 'yes', 3.14, False]
>>> l[3] = True
>>> l
[114514, 'yes', 3.14, True]
>>> l[1:3] = ['no', 1.414]
>>> l
[114514, 'no', 1.414, True]

列表可以用append()方法追加元素到末尾,或是用insert()方法把元素插入到指定的位置:

1
2
3
4
5
6
>>> l.append('right')
>>> l
[114514, 'no', 1.414, True, 'right']
>>> l.insert(2, 3.14)
>>> l
[114514, 'no', 3.14, 1.414, True, 'right']

pop()方法删除末尾的元素,pop(i)删除第i个元素:

1
2
3
4
5
6
7
8
>>> l.pop()
'right'
>>> l
[114514, 'no', 3.14, 1.414, True]
>>> l.pop(3)
1.414
>>> l
[114514, 'no', 3.14, True]

这里列出列表支持的操作:(字符串、列表和元组通用的操作见下面)

运算 结果
s[i] = x s的第i项替换为x
s[i:j] = t sij的切片替换为t的内容
del s[i:j] 等价于s[i:j] = []
s[i:j:k] = t s[i:j:k]的元素替换为t的元素
del s[i:j:k] s中删除s[i:j:k]的元素
s.append(x) x添加到s的末尾
s.clear() 删除s的所有项,等价于del s[:]
s.copy() s的浅拷贝,等价于s[:]
s.extend(t)s += t t的内容添加到s的末尾
s *= n 重复s的内容n次并更新
s.pop()s.pop(i) 删除s的最后一项或第i
s.remove(x) 删除s中第一个等于x的一项
s.reverse() s逆序并更新

列表的元素也可以是另一个列表:

1
2
3
4
5
6
7
8
9
10
11
>>> l = [[1, 2, 3], [4, 5]]
>>> l
[[1, 2, 3], [4, 5]]
>>> len(l)
2
>>> l[0]
[1, 2, 3]
>>> len(l[0])
3
>>> l[0][2]
3

innot in用于检测元素是否在序列内:

1
2
3
4
5
6
7
8
9
10
11
>>> l = [114514, 'yes', 3.14, False]
>>> 114514 in l
True
>>> True in l
False
>>> True not in l
True
>>> 'a' in 'abcde'
True
>>> 'bcd' in 'abcde'
True

list()把对象转换为列表:

1
2
>>> list('114514')
['1', '1', '4', '5', '1', '4']

元组(Tuple)

元组和列表的唯一区别是不可变,除了修改的操作以外,列表支持的操作元组都支持:

1
2
3
4
5
6
7
8
9
10
11
>>> t = (114514, 'yes', 3.14, False)
>>> t
(114514, 'yes', 3.14, False)
>>> len(t)
4
>>> t[0]
114514
>>> t[1:3]
('yes', 3.14)
>>> 3.14 in t
True

特别要注意的是,如果要定义空的元组,可以写成()

1
2
3
>>> t = ()
>>> t
()

但是定义只有一个元素的元组,不能这么写:

1
2
3
>>> t = (1)
>>> t
1

此时t是一个整数1,因为()被当成了数学运算的小括号处理。因此,应该加一个逗号,来区分:

1
2
3
>>> t = (1,)
>>> t
(1,)

这里再把字符串、列表和元组支持的通用操作总结一遍:(按优先级升序排列,innot in优先级相同)

运算 结果
x in s s中的某项等于x,返回真
x not in s s中的某项等于x,返回假
s + t st拼接
s * nn * s s与自身进行n次拼接
s[i] s的第i项,起始为0
s[i:j] sij的切片
s[i:j:k] sij步长为k的切片
len(s) s的长度
min(s) s的最小项
max(s) s的最大项
s.index(x[, i[, j]]) xs中首次出现项的下标(在i及之后且在j之前)
s.count(x) xs中出现的总次数

tuple()把对象转换为元组:

1
2
3
4
>>> tuple('114514')
('1', '1', '4', '5', '1', '4')
>>> tuple(['1', '1', '4', '5', '1', '4'])
('1', '1', '4', '5', '1', '4')

集合(Set)

集合是一种唯一性的无序集。集合不能放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证集合内部不会有重复元素。集合可以用set()或者花括号{}创建:

1
2
3
4
5
6
>>> s1 = {1, 2, 3}
>>> s1
{1, 2, 3}
>>> s2 = set([1, 2, 3])
>>> s2
{1, 2, 3}

集合会自动过滤重复元素:

1
2
3
>>> s = set('114514')
>>> s
{'5', '1', '4'}

add()方法和remove()方法可以添加和删除元素:

1
2
3
4
5
6
7
8
9
>>> s.add('2')
>>> s
{'5', '1', '4', '2'}
>>> s.add('1')
>>> s
{'5', '1', '4', '2'}
>>> s.remove('1')
>>> s
{'5', '4', '2'}

集合可以做数学意义上的交集、并集等操作:

1
2
3
4
5
6
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

字典(Dictionary)

字典是一种映射类型,在其它语言中也叫map,以键-值(key-value)的方式存储,具有极快的查找速度。因为和集合类似的原理,字典的键只能是不可变对象。
字典可以以类似下标的方式通过键来取出对应的值:

1
2
3
4
5
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d['a']
1

dict()也能创建一个字典:

1
2
3
4
>>> dict([('a', 1), ('b', 2), ('c', 3)])
{'a': 1, 'b': 2, 'c': 3}
>>> dict(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}

由于一个键只能对应一个值,多次对同一个键赋值会把前面的值覆盖:

1
2
3
4
5
6
>>> d['a'] = 1
>>> d['a']
1
>>> d['a'] = 5
>>> d['a']
5

innot in用于判断键是否存在:

1
2
3
4
>>> 'a' in d
True
>>> 'd' in d
False

下标的键不存在会报错,但用get(key[, default])方法,如果key不存在,会返回空值None或者自己指定的default

1
2
3
4
5
>>> d.get('b')
2
>>> d.get('d')
>>> d.get('d', 114514)
114514

注意:返回None时在Python交互模式不显示结果。

pop()方法用于删除键及其对应的值:

1
2
3
4
5
6
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d.pop('a')
1
>>> d
{'b': 2, 'c': 3}

变量与常量

变量用标识符表示,标识符(即变量名)一般只能由大小写字母、数字和下划线_组成,不能以数字开头。虽然Python支持任何Unicode字符作为标识符,但是非常不推荐这么做。
赋值运算符=用于给变量赋值:

1
a = 1

变量a是一个整数,标识符为a,值为1

同一个变量可以反复赋值,而且可以赋值不同类型:

1
2
3
4
5
6
7
8
9
>>> a = 1
>>> a
1
>>> a = 'ABC'
>>> a
'ABC'
>>> a = [1, 2, 3]
>>> a
[1, 2, 3]

这种变量本身类型不固定的语言称之为动态语言,C、Java等静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。

+=等赋值运算符将二元运算与赋值合为一体,x += 1实际上就等价于x = x + 1。类似地,还有-=*=/=//=%=**=>>=<<=&=^=|=等等。

1
2
3
4
>>> a = 1
>>> a += 1
>>> a
2

另外,有一些标识符被作为Python的保留字,称为关键字。关键字在Python中有特殊的用途,不能作为变量名使用。

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
# 以下是Python中的所有关键字
False
True
None
and
as
assert
async
await
break
class
continue
def
del
elif
else
except
finally
for
from
global
if
import
in
is
lambda
nonlocal
not
or
pass
raise
return
try
while
with
yield

常量就是不变的变量。通常用全部大写的变量名来表示常量:

1
PI = 3.14159265359

但事实上PI仍然是一个变量,仍然可以被赋值。用全部大写的变量名表示常量只是一个习惯上的用法。

Python中内置了3个常量,尝试给这3个常量赋值会报错。这3个常量分别是布尔值类型的TrueFalse,以及空值None
NoneNoneType类型的唯一值。虽然None表示空,但并不等同于空字符串、空列表或者False。如果要判断一个值是否为None,推荐使用isis not

0%