【Python】第二章 内置数据类型
该文章内容整理自《Python编程:从入门到实践》、《流畅的Python》、以及网上各大博客
文章目录
- 内置数据类型
- 变量
- 基本运算
- 特殊值
- 布尔值
- 数字类型
- 序列
- 字符串
- 转义字符
- 操作
- 内置函数
- Unicode字符串
- 列表
- 操作
- 初始化
- 元组
- 打包和解包
- xrange
- buffer
- bytes
- bytearray
- buffer
- 映射
- 哈希
- 集合
- 字典
内置数据类型
变量
Python中变量的命名规则和C语言一致,变量名只能包含字母、数字和下划线,且变量名可以以字母或下划线开头,但不能以数字开头。如果允许变量名开头是数字,则无法区分变量名和数字类型,例如:如果变量名 091合法,则程序无法区分这个变量和数字 091。另外,有些数字可能含有字母,如浮点数 1E10。程序设计语言不能存在歧义,因此,需要约定变量名开头不能是数字,以便区分变量与数字
Python定义变量时不需要声明变量类型,实际上,Python并没有像C语言中的变量的概念。在C语言中,变量是面向内存的。因此在定义变量时需要表明变量所占空间的大小、存储的格式、以及使用一个标识符指向这个变量空间
而Python中只有标识符和对象的概念,如a=3中,系统首先会创建标识符a,然后创建对象3,最后将标识符a关联到对象3中(如果标识符已存在,则直接将对象关联到现有的标识符a中)。因此标识符本身没有类别,标识符关联的对象才有类别,而Python中使用函数type(name)查看的正是对象的类型。同时,标识符在创建时必须关联到一个对象,且创建后可以关联到任何不同类型的对象
Python中包括函数在内的一切皆为对象,理解变量标识符和对象之间的关系对于理解Python中其他编程思想至关重要
Python中对象具有一下属性:
- 标识:唯一识别,不可改变,使用id(obj)查看
- 类型:不可改变
- 值:根据类型可分为可变(如列表(但是这里的可变仅仅是指可将列表内元素关联到其他不同的值)、字典等)、以及不可变(如整数、浮点数、布尔数、元组等)
而对于标识符,一个对象可被多个标识符关联,且标识符只存在与特定的命名空间中
因此,python是强类型的动态脚本语言。强类型语言是指使用强制数据类型定义的语言,没有强制类型转化前,不允许两种不同类型的变量相互操作;弱类型语言是指一个变量可以赋不同数据类型的值,允许将一块内存看作多种类型,比如允许直接将整型变量与字符变量相加的隐式变换过程。静态是指数据类型是在编译期进行检查的,也就是说变量在使用前要声明变量的数据类型,这样的好处是把类型检查放在编译期,提前检查可能出现的类型错误;动态是指在运行期间进行数据类型检查,也就是在编写代码的时候可以不指定变量的数据类型。而脚本语言是指运行代码只需要一个解释器,不需要编译的语言
基本运算
类型转换
- int(x [,base ]):将x转换为一个整数
- long(x [,base ]):将x转换为一个长整数
- float(x):将x转换到一个浮点数
- complex(real [,imag ]):创建一个复数
- str(x):将对象 x 转换为字符串
- repr(x):将对象 x 转换为表达式字符串
- eval(str):用来计算在字符串中的有效Python表达式,并返回一个对象
- tuple(s):将序列 s 转换为一个元组
- list(s):将序列 s 转换为一个列表
- chr(x):将一个整数转换为一个字符
- unichr(x):将一个整数转换为Unicode字符
- ord(x):将一个字符转换为它的整数值
- hex(x):将一个整数转换为一个十六进制字符串
- oct(x):将一个整数转换为一个八进制字符串
运算符
相比于C语言,Python提供整除’//’、幂’**’。Python中各运算符的优先级如下
需要注意:
- 在除法’/'以及不同类型数据混合运算时都会转换为浮点数
- Python中运算结果总是向负无穷的方向舍入。如 1//2 = 0,(-1) / /2 = -1,1//(-2) = -1,(-1)//(-2) = 0
- Python 将 pow(0, 0) 和 0 ** 0 定义为 1,这是编程语言的普遍做法
- Python和C语言一样支持连等式,即能使用 a = b = c 。但是对于自增类型,C语言同样能够连等,而Python则不能,即在Python中, a += b += c 是不成立的,一个等式里面只能有一个 += 。这样一来,C语言中能够使用异或运算来交换两个整型数,如 a ^= b ^= a ^= b,在Python中则不能使用。然而,Python中提供了打包和解包的方式,使得能够更方便的交换两个变量,如a, b = b, a(对于复杂对象而言,该等式确实是使用打包和解包的方式交换对象,但对于简单的对象(整数等),Python 提供了内部的优化方法来交换对象)
- Python不同于C语言的一个地方是Python支持连续不等式,如 0 < x < 3
- is 和 ==,或 is not 和 != 并不相同。is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。如
x = [1, 2, 3]
y = [1, 2, 3]
print(x == y) # True
print(x is y) # False
print(id(x)) # 2194144817928
print(id(y)) # 2194144817288
- Python 没有自增运算符 ++。出于性能考虑,Python使用小整数对象缓冲池 small_ints 缓存了[-5,257)之间的整数,该范围内的整数在Python系统中是共享的。所以当变量自增后就已经指向另一个对象,并不是C语言一样自增只是将变量内存空间数值加一
特殊值
无穷大和无穷小
Python中用 float(‘inf’) 表示正无穷,-float(‘inf’) 或 float(’-inf’) 表示负无穷。其中,inf 可写成 Inf。此时无穷大加上或乘以某个数仍为无穷大,而有些操作时未定义的并会返回一个 NaN,如无穷大加上无穷小,或者无穷大除以无穷大。此外,可使用 math.isinf() 来判断变量是否为无穷值。float(‘inf’) 为float类型
NaN
NaN在数学表示上表示一个无法表示的数,Python中也可以使用 float(‘nan’) 来定义nan变量。此时nan与nan运算仍为nan。同样也可使用 math.isnan() 来判断判断变量是否为 NaN,但是若两个NaN变量使用 == 进行比较却会返回False,而两个 inf 变量用 == 比较则会返回True。float(‘nan’) 为float类型
空值None
与C语言不同,Python中是没有NULL,但存在相近意义的None。None表示空值,它是一个特殊 Python 对象,其类型是NoneType。None在 Python 解释器启动时自动创建,解释器退出时销毁。在一个解释器进程中只有一个 None 存在,因为不可能有其他对象会使用 None 已占用的内存
- None 不支持任何运算也没有任何内建方法
- None 和任何其他的数据类型比较永远返回False
- None 有自己的数据类型NoneType,不能创建其他NoneType对象(它只有一个值None)
- None 与0、空列表、空字符串不一样
- 可以将 None 赋值给任何变量,也可以给 None 变量赋值
- None 无像len、size等属性,要判断一个变量是否为None,直接使用a is None
Python原生的None和pandas、numpy中的numpy。NaN尽管在功能上都是用来标示空缺数据。但它们的行为在很多场景下确有一些相当大的差异
- 在pandas中, 如果其他的数据都是数值类型, pandas会把None自动替换成NaN
- None能直接被导入数据库作为空值处理, 包含NaN的数据导入时会报错
- numpy和pandas的很多函数能处理NaN,但是如果遇到None就会报错
- None和NaN都不能被pandas的groupby函数处理,包含None或者NaN的组都会被忽略
布尔值
在Python中,可以直接用True、False表示布尔值(注意大小写)
and、or、not属于布尔运算,且是按优先级升序排列。同时,Python中的布尔运算和C语言一样遵循短路原则,即只有在第一个参数为假值时才会对第二个参数求值;只有在第一个参数为真值时才会对第二个参数求值。另外,not 的优先级比非布尔运算符低,因此 not a == b 会被解读为 not (a == b)
数字类型
Python 支持四种不同的数字类型:
- 整型:Python2在32位机器上,整型取值范围为-2^31~2^31-1;在64位机器上,取值范围为-2^63~2^63-1。而在Python3中整型长度无限制
- 长整型:Python2中长整型无长度限制,长整型需要在最后添加大写或小写的L,如果发生溢出会自动将整型数据转换为长整型。而在Python3中长整型和整型统一归为整型
- 浮点型:由整数部分与小数部分组成,也可以使用科学计数法表示(如2.5e2)
- 复数:复数由实数部分和虚数部分构成虚数部分需要加上 j 或 J ,如a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型
数学函数
- abs(x):返回整型数的绝对值
- ceil(x):返回整型数的上入整数
- cmp(x, y):如果 x < y 返回 -1,如果 x == y 返回 0,如果 x > y 返回 1。 Python 3 已废弃 ,使用 (x>y)-(x<y) 替换
- exp(x):返回e的x次幂(ex)
- fabs(x):返回浮点数的绝对值
- floor(x):返回整型数的下舍整数,如math.floor(4.9)返回 4
- log(x[, base]):返回以base为基数的x的对数,base默认为e
- log10(x):返回以10为基数的x的对数
- max(x1, x2,…):返回给定参数的最大值
- min(x1, x2,…):返回给定参数的最小值
- modf(x):返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示
- divmod(x, y):返回一个元组,为 (x // y, x % y)
- pow(x, y):返回x的y次幂
- round(x [,n]):返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数
- sqrt(x):返回数字x的平方根,数字可以为负数,返回类型为实数
- acos(x):返回x的反余弦弧度值
- asin(x):返回x的反正弦弧度值
- atan(x):返回x的反正切弧度值
- atan2(y, x):返回给定的 x 及 y 坐标值的反正切值
- cos(x):返回x的弧度的余弦值
- hypot(x, y):返回欧几里德范数 sqrt(xx + yy)
- sin(x):返回的x弧度的正弦值
- tan(x):返回x弧度的正切值
- degrees(x):将弧度转换为角度
- radians(x):将角度转换为弧度
随机数函数
- choice(seq):从序列的元素中随机挑选一个元素
- randrange ([start,] stop [,step]):从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1
- random():在[0,1)范围内随机生成下一个实数
- seed([x]):改变随机数生成器的种子seed。Python会自动选择seed
- shuffle(lst):将序列的所有元素随机排序
- uniform(x, y):在[x,y]范围内随机生成下一个实数
常量
pi:圆周率π
e:自然常数e
Python中 cmath 模块的函数跟 math 模块函数基本一致,区别是 cmath 模块运算的是复数,math 模块运算的是数学运算
序列
Python包含6中内建的序列,即字符串、Unicode字符串、列表、元组、buffer对象和 xrange 对象。一般来说,一个序列对象至少需要实现如下两个方法:
- __len__方法:该方法返回序列长度,也即序列中元素个数
- __getitem__方法:该方法需要一个整型下标参数,并返回序列中该下标的元素的值
序列通用的操作包括:索引、长度、组合(序列相加)、重复(乘法)、分片、检查成员、遍历、最小值和最大值
序列相关函数
- len(L):返回序列的长度
- max(L):返回序列中的最大值
- min(L):返回序列中的最小值
- sum(L):返回序列的元素的和(只有数字型才可以)
- any(L):返回布尔值,序列中不都为空、0、False,则返回 True
- all(L):返回布尔值,序列中都不为空、0、False,则返回 True
- reversed(L):返回反向顺序的可迭代序列,注意并不是返回序列。因此一般在 for 循环中使用,如 for x in reversed(s)。若要直接使用需要先用 list() 转换为列表
- sorted(L):默认按升序对序列进行排序
- zip(L1, L2, …):返回几个序列压缩成的新序列,且返回的只是可迭代对象直接使用前需要先转换为列表。另外,zip()可以同时遍历多个列表,并且在 Python3 中zip()返回的是生成器,而 Python2 中为列表。如果不同列表长度不等,则zip()会提前终止。如
zip([1, 2, 3], [1, 2, 3], [1, 2, 3])
# [(1, 1, 1), (2, 2, 2), (3, 3, 3)]zip([1, 2, 3], [1, 2, 3], [1, 2])
# [(1, 1, 1), (2, 2, 2)]zip("Hello", "World")
# [('H', 'W'), ('e', 'o'), ('l', 'r'), ('l', 'l'), ('o', 'd')]
- eunmerate(L):返回序列的枚举对象,其中每个元素为包含下标和值的元组,返回的同样只是可迭代对象。推荐尽量使用enumerate来改写那种将range与列表访问结合的序列遍历代码。同时,可以给enumerate提供第二个参数,以指定开始计数器时所用的值,默认为0。如
enumerate([1, 2, 3])
# [(0, 1), (1, 2), (2, 3)]color = ['red','black','write','green']
for i in range(len(color)): print(i,color[i])for i,value in enumerate(color): print(i,value)
- map(function, iterable, …):对参数序列中的每一个元素(或多个参数的每一个相同位置元素)调用function函数,其返回值组成一个新序列。Python2中返回的是列表,Python3中返回的是可迭代对象。如
def square(x):return x ** 2
map(square, [1,2,3,4,5]) # [1, 4, 9, 16, 25]
map(lambda x, y: x+y, [1, 3, 5], [2, 4, 6]) # [3, 7, 11]
- reduce(function, iterable[, initializer]):函数先对序列中的第 1、2 个元素调用function,得到的结果再与第3个元素调用 function,其结果再与下一个元素调用函数,最后返回最终结果。若指定initializer,则一开始先用initializer与第1个元素调用函数。如
reduce(lambda x, y: x+y, [1,2,3]) # 1+2+3
- filter(function, iterable):将序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新序列中。Python2返回列表,Python3返回可迭代对象。如
filter(lambda n: n%2==1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# [1, 3, 5, 7, 9]
字符串
Python2 提供 str 和 unicode,Python3 中修改为 bytes 和 str,bytes为原始的8位值,str 包含 unicode 字符,在进行编码转换时使用 decode() 和 encode() 方法。Python不支持单字符类型,单字符在Python中也是作为一个字符串使用。Python中字符串可用单括号或者双括号括起来,这种灵活性使得能在字符串中包含引号可撇号。另外,Python2中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在使用中文字符串时会报错。此时需要在文件开头加入 # -*- coding: UTF-8 -*- 或者 # coding=utf-8 指定编码。注意 = 号两边没有空格。然而Python3则默认使用utf-8编码,所以可以正常解析中文,无需指定 UTF-8 编码
转义字符
Python中的转义字符和C语言中的转义字符大致相同。注意其中的续行符,Python支持三引号,即一对连续的单引号或者双引号,其允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。三引号和续行符的区别如下
# a包括换行符
a = '''hi
there'''# b不包括换行符,反斜杠作为续行符
b = 'hi \
there'
另外,三引号除了允许字符串跨行,还能作为多行注释(#为单行注释)
操作
a. 字符访问:使用索引[]获取字符串中的字符。另外,在Python中用-1表示最后一个下标位置,-2表示倒数第二个下标位置,以此类推。注意Python只支持通过索引获得字符串字符,不支持通过索引修改字符串中单个字符
b. 获取子串:使用[ : ]截获字符串中的一部分,也称字符串切片。其完整表达式为[start : end : step]。start省略时默认为0,end省略时默认为-1,step省略时默认为1。意思是从字符串start下标开始,每step个字符提取一个字符,直至end-1位置为止,最后返回由这些提取字符组成的子串。start和end也支持负数下标,表示倒数位置,而step也支持负数,表示逆序,如-1表示从后往前一个一个字符提取,-2表示从后往前每隔两个字符提取。另外,step=-1时并不总能将字符串逆序,如对一个中文字符串,直接使用step=-1则会报错
c. 字符串连接:Python中字符串拼接有7种方式
- + :使用这种方式进行字符串连接的操作效率低下,因为python中使用 + 拼接两个字符串时会生成一个新的字符串,生成新的字符串就需要重新申请内存,当拼接字符串较多时自然会影响效率。如
s = 'Hello' + ' ' + 'World' + '!'
- ():python遇到未闭合的小括号,自动将多行拼接为一行。如
s = ('Hello'' ''World''!')
- str.join():这种方式一般常使用在将集合转化为字符串,’’.join()其中’'可以是空字符,也可以是任意其他字符,当是任意其他字符时,集合中字符串会被该字符隔开。应优先使用join函数,而不是+操作。如
s = ''.join(['Hello', ' ', 'World', '!'])
- str.format():通过这种方式拼接字符串需要注意的是字符串中{}的数量要和format方法参数数量一致,否则会报错。如
s = '{} {}!'.format('Hello', 'World')
- %:这种方式与str.format()使用方式基本一致。如
s = '%s %s!' % ('Hello', 'World')
- Template:Template的实现方式是首先通过Template初始化一个字符串。这些字符串中包含了一个个key。通过调用substitute或safe_subsititute,将key值与方法中传递过来的参数对应上,从而实现在指定的位置导入字符串。这种方式的好处是不需要担心参数不一致引发异常。如
from string import Template
s1 = Template('${a} ${b}!')
s1.safe_substitute(a='Hello', b='World') # 'Hello World!'s2 = Template('${a} ${b} ${c}!')
s2.safe_substitute(a='Hello', b='World') # 'Hello World ${c}!'
- F-strings:在python3.6.2版本中,PEP 498 提出一种新型字符串格式化机制,被称为“字符串插值”或者更常见的一种称呼是F-strings,F-strings提供了一种明确且方便的方式将python表达式嵌入到字符串中来进行格式化。在F-strings中我们也可以执行函数,而且F-strings的运行速度很快,比%-string和str.format()这两种格式化方法都快得多。如
a = 'Hello'
b = 'World'
s1 = f'{a} {b}!'def power(x):return x*x
x = 5
s2 = f'{x} * {x} = {power(x)}' # '5 * 5 = 25'
d. 字符串乘法。Python中支持将字符串与整数相乘。如
s = 'M' *3 # 'MMM'
e. 成员运算符。使用in或not in判断字符串中是否含有给定字符,返回True或False
f. 原始字符串。在字符串第一个引号前加上字母"r"或"R"表示为原始字符串,表示字符串中所有字符都是直接按照字面意思来使用。另外,在字符串前添加"u"或"U"则表示字符串是一个Unicode字符串
g. 格式字符串。Python 支持使用 % 格式化字符串的输出 。字符串格式化使用与C语言中一样的语法,如
print("My name is %s and weight is %d kg!" % ('Zara', 50) )
格式化操作符辅助命令
Python2.6 开始,新增了一种格式化字符串的函数 str.format(),增强了字符串格式化的功能,如
print("My name is {} and weight is {} kg!".format ('Zara', 50) )print("My name is {1} and weight is {0} kg!{1}".format (50, 'Zara') )# 关键字参数
print("My name is {name} and weight is {weight} kg!".format (name='Zara', weight=50))l = ['Zara', 50]
print("My name is {0[0]} and weight is {0[1]} kg!".format (l))# 使用列表设置参数,其中0是必须的d = {"name": "Zara", "weight": 50}
print("My name is {name} and weight is {weight} kg!".format (**d))# 使用字典设置参数# 填充 {0:[填充字符][对齐方式 <^>][宽度]}.format()
print('{0:*>10}'.format(20)) # 右对齐 '********20'
print('{0:>10}'.format(20)) # 右对齐 ' 20'
print('{0:*<10}'.format(20)) # 左对齐 '20********'
print('{0:*^10}'.format(20)) # 居中对齐 '****20****'# 进制
print('{0:b}'.format(10)) # 二进制 '1010'
print('{0:o}'.format(10)) # 八进制 '12'
print('{0:x}'.format(10)) # 十六进制 'a'
print('{0:#x}'.format(10)) # 十六进制 '0xa'
print('{0:x}'.format(10)) # 十六进制 '0xA'# 格式
print('{0:.2f}'.format(1/3)) # '0.33'
print('{0:+.2f}'.format(1/3)) # 输出正号 '+0.33'
print('{0:+.2f}'.format(-1/3)) # 输出负号 '-0.33'
print('{0: .2f}'.format(1/3)) # 输出空格 ' 0.33'
print('{0: .2f}'.format(-1/3)) # 输出负号 '-0.33'
print('{0:.0f}'.format(3.14)) # 不带小数点 '3'
print('{0:.2%}'.format(1/3)) # 百分比格式 '33.00%'
print('{:,}'.format(123456789)) # 千分位格式化 '123,456,789'
print('{:.2e}'.format(123456789)) # 指数记法 '12.34e+07'# 用大括号转义大括号大括号
print("{{test}}test{}".format("test")) # {test}testtest
h. 有六种常见的字符串匹配方法
- re.match(pattern, s):尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功则返回none
- re.search(pattern, s):扫描整个字符串并返回第一个成功的匹配
- re.sub(pattern, replace, s):用于替换字符串中的匹配项
- compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用
- pattern.findall(s):在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表
- re.finditer(pattern, s):和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回
内置函数
- string.capitalize():把字符串的第一个字符大写
- 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.isdigit():如果 string 只包含数字则返回 True 否则返回 False
- string.islower():如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
- 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 中所有的元素合并为一个新的字符串
- string.ljust(width):返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
- string.lower():转换 string 中所有大写字符为小写
- string.lstrip():截掉 string 左边的空格
- string.maketrans(intab, outtab]):maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标
- 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()函数,不过是从右边开始查找
- string.rindex( str, beg=0,end=len(string)):类似于 index(),不过是从右边开始
- string.rjust(width):返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
- string.rpartition(str):类似于 partition()函数,不过是从右边开始查找
- string.rstrip():删除 string 字符串末尾的空格
- string.split(str="", num=string.count(str)):以 str 为分隔符切片 string,如果 num 有指定值,则仅分隔 num+1 个子字符串
- 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.translate(str, del=""):根据 str 给出的表转换 string 的字符,要过滤掉的字符放到 del 参数中
- string.upper():转换 string 中的小写字母为大写
- string.zfill(width):返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0
Unicode字符串
当需要处理包含非ASCII码字符的文本时,就需要用到Unicode字符串。原先,在以ASCII码为中心的语言和环境中,字节和字符被当做相同的事物。由于一个字节只能有256个值,这些环境就受限为只支持 256个字符。而Unicode码则有数万个字符,每个Unicode字符占用多个字节
标准的Python字符串为字节字符串,即一个Python字符占用一个字节。而 Python 的 Unicode 码字符足以表示所有支持Unicode字符,类似于 Python 中的长整数。然而,当把 Unicode 字符传递给给一些基于字节的函数的时候,如文件的 write() 方法或网络套接字的 send() 方法,此时则必须要选择该如何表示这些 Unicode 字符为字节字符。从 Unicode 码到字节串的转换被叫做编码,反之称为解码
UTF-8 编码能处理任何的 Unicode 字符,它也是与ASCII码向后兼容的。UTF-8 在 Unix 上应用广泛,但其缺点是对东方文字是非常低效的。而UTF-16 编码在微软的操作系统和Java环境下应用较广。与 UTF-8 编码相反,UTF-16 编码对西方语言是比较低效,但对于东方语言是更有效率的。UCS-2编码为 UTF-16 的一个变体
ISO-8859编码系列是ASCII码的超集,且不支持所有的Unicode码字符,而只支持一些特别的语言。ISO-8859-1,即Latin-1,包括大多数的西欧和非洲语言,但是不含阿拉伯语。ISO-8859-2,即Latin-2,包括许多东欧的语言,如匈牙利语和波兰语
列表
列表是Python中最基本的数据结构,其数据项不需要具有相同的类型。不同于C语言,Python允许在列表、元组和字典的末尾添加一个尾随逗号。因为如果列表、元组或字典的元素分布在多行中,则更容易添加更多元素,不必记住在上一行中添加逗号。这些行也可以重新排序,而不会产生语法错误。允许尾随逗号也可以使编程代码更容易生成。如
_list = [1, 2, 3,]
_tuple = ('a', 'b', 'c',)
_dict = {"A": [1, 5], "B": [6, 7],
}
操作
- 访问:使用索引[]获取列表中的元素。另外,在Python中用-1表示最后一个下标位置,-2表示倒数第二个下标位置,以此类推
- 切片:使用[ : ]截获列表中的一部分,也称切片。其完整表达式为[start : end : step]。start省略时默认为0,end省略时默认为-1,step省略时默认为1。意思是从列表start下标开始,每step个元素提取一个元素,直至end-1位置为止,最后返回由这些提取元素组成的列表。start和end也支持负数下标,表示倒数位置,而step也支持负数,表示逆序,如-1表示从后往前一个一个元素提取,-2表示从后往前每隔两个元素提取。Python中常用切片[:]的方式直接复制一个列表。但是为了易读性,一般不推荐在切片操作内同时指定start、end和step
- 更新:
- list.append(obj):在列表末尾添加新的对象
- list.extend(seq):在列表末尾一次性追加另一个序列中的多个值,可用于新列表扩展原来的列表
- list.insert(index, obj):将对象插入列表
- 删除:
- del list[index]:删除列表中下标index处的元素
- list.pop([index=-1]):移除列表中下标index处的元素(默认最后一个元素),并且返回该元素的值
- list.remove(obj):移除列表中某个值的第一个匹配项
- 列表运算符:列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表
- 排序:
- list.sort(cmp=None, key=None, reverse=False):对原列表进行永久性排序
- sorted(list, cmp=None, key=None, reverse=False):对原列表进行临时性排序并返回排序结果 ,原列表不变
- list.reverse():反向列表中元素。或直接使用切片list[::-1]
- 其他:
- cmp(list1, list2):比较两个列表的元素。但是在 Python3 中已经去掉cmp()函数
- list(seq):将元组转换为列表
- list.count(obj):统计某个元素在列表中出现的次数
- list.index(obj):从列表中找出某个值第一个匹配项的索引位置
- list.copy():返回列表“一层”深复制。即若为一维列表则为深复制,若为二维列表则为浅复制
对于对象直接赋值、浅复制和深复制
- 直接赋值 b = a:是指对象的引用,使得 a 和 b 都指向同一个对象
- 浅复制 b = a.copy():a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象
- 深复制 b = copy.deepcopy(a): copy 模块提供 deepcopy 方法,使得 a 和 b 完全复制了父对象及其子对象,两者是完全独立的
对于sort()和sorted()方法中的三个参数:
- cmp:cmp可以为一个具有两个参数的自定义比较函数。也可以使用lambda函数,如sorted(a, cmp=lambda x, y: x-y),或者sorted(a, cmp=lambda x, y: 1)。在Python2.4前,sort()和sorted()方法没有提供key参数,但是提供了其他语言都常用的cmp参数来让用户指定比较函数 ,默认值为None。而在Python3中为了节省内存已经取消cmp参数,若要在Python3中使用cmp参数,则需要从模块functools中导入函数cmp_to_key,然后将其赋值给key。如
from functools import cmp_to_key
nums = [1, 3, 2, 4]
nums.sort(key=cmp_to_key(lambda a, b: a - b))
- key:从Python2.4开始,sort()和sorted()方法增加了key参数来指定一个函数,此函数将在每个元素比较前被调用。相比于用cmp直接比较任意两个原始元素,key函数能把原始元素转换成可比较的key,然后用元素的key代替元素去参与比较。如果元素key之间的比较操作比原始元素之间的比较操作效率高的话,那么就能提高性能。此外,Python还提供了operator模块中的itemgetter与attrgetter方法,从2.6开始还增加了methodcaller方法。使用这些方法,上面的操作将变得更加简洁和快速。如
student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10),
]student_objects = [Student('john', 'A', 15), Student('jane', 'B', 12),Student('dave', 'B', 10),
]# 类对象Student有name、grade和age三个数据成员sorted(student_tuples, key=lambda student: student[2])
sorted(student_objects, key=lambda student: student.age)from operator import itemgetter, attrgetter
sorted(student_tuples, key=itemgetter(2))
sorted(student_objects, key=attrgetter('age'))# operator模块还允许多级的排序
sorted(student_tuples, key=itemgetter(1, 2))
sorted(student_objects, key=attrgetter('grade', 'age'))
# 先排第二个元素,再排第三个元素
- reverse:sort()和sorted()方法默认升序排序,若要降序排序,则需要将reverse设为True
另外,从Python2.2开始,sort()和sorted()排序被保证为稳定的,且reverse参数的使用不改变其稳定性
初始化
除了能够使用range()循环加append(),或用乘法(如list = [0] * 1000)初始化列表外,还能使用列表解析的方法初始化列表。在时间上,创建相同大小的列表,使用乘法时速度最快,列表解析其次,使用循环append()最慢
列表解析
其表达式为[expression for iter_val in iterable if cond_expr],如
l = [(x,y) for x in [1, 2] for y in [1, 4] if x != y]
列表解析是Python中功能强大的工具。使用列表解析,C语言中的快速排序在Python中只需要一行就能完成。这里用到短路原则,当arr为空时,不再执行后面的递归,直接返回False。如
def qsort(arr):return arr and qsort([x for x in arr[1:] if x < arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x >= arr[0]])
元组
直观而言,列表 list 和元组 tuple 之间的区别在于列表元素是可变的,元组元素是不可变的。引入元组最关键的一点是其语法的灵活和便捷性,提高了编程体验。如
- 使得 Python 中函数能返回多个值。当函数需要返回多个值时,系统会将这些值打包成一个元组,所以实际上函数只返回了一个值。如
def get():name = "A"age = 23return name, age
- 相对于列表而言,元组是不可变的,这使得它可以作为字典的键,或者放到集合里,而列表则不行。
- 元组放弃了对元素的增删,使得内存结构设计上变的更精简,换取的是性能上的提升:创建元组比列表要快,存储空间比列表占用更小。所以就出现了“能用元组的地方就不用列表”的说法。并且在多线程并发的时候,元组是不需要加锁的,不用担心安全问题,编写也简单多了
打包和解包
Python支持在赋值语句的左边有多个被逗号分开的对象,那样的一个多赋值也被称为解包赋值。 此时,右边的值必须是一个序列,而且它的数目要和左边逗号分隔的对象一样多,当变量和序列当中的数量不一致时,可以在变量前面添加一个*,表示以列表形式接受元素。序列的每一项都被从左到右依次赋给相对应的目标值。反之,赋值语句的右边有多个被逗号分开的对象时,左边则打包成一个元组
t = (1, 2, 3, 4)
a, b, c, d = t
x, *y, z = t # x = 1, y = [2, 3], z = 4# 不使用中间变量交换变量的值
a, b, c = b, c, a
# 对复杂对象而言确实是使用打包和解包来交换对象,但对于一些简单对象,Python内部使用了优化方法来提高交换效率
xrange
上述序列都有一个共同点,即当序列对象创建时需要开辟专门的内存空间以保存序列中的所有元素。换句话说,这些序列对象本质上是一个集合。然而,一个序列对象不必要保存所有的元素。一般来说,一个序列对象至少需要实现如下两个方法
- __len__方法:该方法返回序列长度,也即序列中元素个数
- __getitem__方法:该方法需要一个可为负的整型下标参数,并返回序列中该下标位置的元素的值
而对于xrange对象来说,其__getitem__方法实现了序列的通项公式,即此时不需要再开辟内存空间保存序列所有元素,只要在访问序列元素时使用通项公式计算即可。因而,在处理有规律的大型序列时,使用xrange对象更能节省内存空间,且更有效率
关于range()、xrange()和rangrange()
Python2中range()返回list,而xrange()返回的是一个xrange对象,所以当需要生成大量数据时使用xrange()会更节省空间。在Python3中,range()这种实现被移除,保留了xrange()的实现,且将xrange()重新命名成range(),所以Python3中range()并不返回list。而对于randrange(),其用法和random一样,但返回是特定范围的一个随机结果而不是该范围的所有数据
可以用 iter(object) 来创建可迭代对象。也可以用 iter() 来判断对象是否为可迭代对象还是容器
if iter(numbers) is iter(numbers):raise TypeError('Must supply a container')
buffer
bytes
Python3 新增 bytes 类型,是指一堆字节的集合,十六进制表现形式,两个十六进制数构成一个 byte,以 b 开头的字符串都是 bytes 类型。 bytes 对象只负责以字节(二进制格式)序列来记录数据,至于这些数据到底表示什么内容,完全由程序决定,且 bytes 为不可变的字节序列
计算机只能存储二进制,字符、图片、视频、音乐等想存到硬盘上,必须以正确的方式编码成二进制后再存,但是转成二进制后不是直接以 0101010 的形式表示的,而是用 bytes 类型来表示。同时,由于 bytes 保存的就是原始的字节(二进制格式)数据,因此 bytes 对象可用于在网络上传输数据
Python 3 中已将 str 和 bytes 完全区分开,不会以任意隐式的方式混用 str 和 bytes。bytes 对象只需在常规的 str 类型前加个 b 以示区分,例如 b’abc’。str转换为bytes时,最好使用encode();bytes转换为str时,最好使用decode(),因为这样不需要使用参数。str是可读的,bytes是不可读的
初始化
- bytes():定义一个空 bytes
- bytes(int):指定字节的bytes,被0填充
- bytes(iterable_of_ints):定义内容,且iterable_of_ints为整型序列,否则报错。如bytes(range(5))
- bytes(bytes or buffer):将bytes或buffer转换为bytes
- bytes(string,encoding[,errors])要指定encoding,如:bytes(‘abc’,‘utf-8’) 或者直接 bytes(b’abc’),b默认encoding为utf-8
操作
- replace():b’abcdef’.replace(b’f’, b’k’)将 f 替换成 k,返回一个bytes
- find():b’abc’.find(b’b’)查找b,返回位置索引
- []:返回下标位置的对应十进制数,如b’abcdef’[2] 返回 99
bytearray
bytearray 是可变的 byte 对象。要构造bytearray对象,方法之一是将bytes数据作为bytearray()方法的参数,或者将str数据和编码作为参数。如bytearray(b’abc’)
操作
- append(int) :增加操作,提供一个整型,根据ASCII码转换为对应的bytes
- insert(index, int):插入操作
- extend(iterable_of_ints):追加iterable_of_ints整型序列
- pop(index=-1):通过索引删除
- remove(value)通过值删除
- clear():清空
- reverse():转置
buffer
只要对象数据支持缓冲区协议,或者简单说这些对象能对底层内存数组或称缓冲的访问,就可以使用buffer对象访问该对象的内部数据而无需进行拷贝。其中,支持缓冲区协议的内置对象包括 bytes 和 bytearray(还有扩展类型 array.array)。buffer对象初始化一般形式为 buffer(object[, offset[, size]])。表示对object对象,从下标offset开始截取size长度的切片,但是该切片只是原序列的一个子视图,而非一个复制。当面对大量数据,想为数据生成各种不同的切片,且不想对原始数据进行拷贝而消耗大量内存空间时,可使用buffer对原序列进行截取,再对buffer进行切片操作。如
s = bytearray(1000000) # 创建一百万个字节的bytearray对象
t = buffer(s, 1) # 从s的第二个字节开始截取
s[1] = 5
t[0] # 此时 t = '\x05'
从Python3开始,memoryview对象已经取代buffer对象,但使用方法相同
映射
哈希
可哈希对象是指对象拥有__hash__()内置函数的对象。对于可哈希的对象执行这个函数将会返回一个整数。可哈希对象判断相等的唯一条件就是两者的哈希值相等。如数值、字母、字符串、元组等不可变的数据结构可哈希;如列表,字典,集合等可变的数据结构不可哈希
因为要保证键的唯一性,所以在set,frozenset,dict这三种数据结构都要求键值key是可hash的
__eq__()和__hash__()的大致实现如下
def __hash__(self):return hash(id(self))
def __eq__(self, other):if isinstance(other, self.__class__):return hash(id(self))==hash(id(other))else:return False
如果一个类型没有定义__eq__()函数,那么它也不应该定义__hash__()。因为如果它定义了__eq__而没有定义__hash__,那么它的实例在某个可哈希集合中将会无效。如果一个类型定义了一个可变对象而且定义了__eq__方法,那么它不应该去定义__hash__方法,因为在哈希集合中要求其中元素的哈希值是不变的
集合
集合是无序不重复可哈希对象的无序集合,其基本功能是进行成员关系测试和消除重复元素
目前有两种内置的集合类型:set 和 frozenset。set类型是可变的,可用add() 和 remove()等方法更改其内容。由于是可变的,没有hash值,因此它不能被当做字典的键值或另一集合的元素。frozenset类型是不可变的且可哈希的,其内容不能再创建后改变,因此它可以用作字典的键值或作为另一个集合的元素
创建
- 使用大括号创建,如 set = {v1, v2}
- set():如set(value)。注意,创建一个空集合必须用 set() 而不是 { },因为 { } 创建的是空字典
- frozenset():如frozenset(value)
set 和 frozenset都支持的操作
- len(set):获取集合中的对象个数
- x in set 或 x not in set:成员关系测试,包含或不包含
- for x in set:循环遍历集合中的条目
- set.isdisjoint(other):判断该集合是否与另外一个集合不相交,不相交则返回True
- set.issubset(other) 或 set <= other :判断该集合是否为另一个集合的子集,而 set < other 判断该集合的是真子集
- set.issuperset(other) 或 set >= other :判断该集合是否为另一个集合的父集,而 set > other 判断该集合的是真父集
- set.union(other,…) 或 set | other | … :求该集合与另一个或多个集合的并集
- set.intersection(other,…) 或 set & other & … :求该集合与另一个或多个集合的交集
- set.difference(other,…) 或 set - other - … :求该集合与另一个或多个集合的差集(该集合中存在但另一集合中不存在)
- set.symmetric_difference(other) 或 set ^ other :求该集合与另一个集合的对称差集(该集合中存在但另一集合中不存在,或另一集合中存在但该集合中不存在的元素集合)
- set.copy() :返回一个新的浅拷贝集合
set和frozenset之间是基于成员进行比较的。如set(‘abc’) == frozenset(‘abc’)返回True,因此set(‘abc’) in set([frozenset(‘abc’)])
set支持但frozenset不支持的操作
- set.add(elem) :向集合中添加一个元素
- set.update(other,…) 或 set |= other :与其它一个或多个集合求并集并将结果赋值给自己
- set.intersection_update(other,…) 或 set &= other :与其它一个或多个集合求交集并将结果赋值为自己
- set.difference_update(other,…) 或 set -= other :与其它一个或多个集合求差集并将结果赋值给自己
- set.symmetric_difference_update(other) 或 set ^= other :与另外一个集合求对称差集并将结果赋值给自己
- set.remove(elem) :从集合中删除一个已存在的元素,不存在则报错
- set.discard(elem) :如果集合中包含该元素则删除它
- set.pop() :由于set集合是无序的,因此该方法会移除并返回一个随机元素
- set.clear() :清除set集合中的所有元素
字典
字典是一种可变容器模型,其值可取任何数据类型,但键必须是可哈希的,即Python中字典的键的存储使用的是哈希而不是红黑树。同时,字典中的键必须为唯一的。因此要判断字典中是否含有某键值对时只需要判断字典中是否含有某个键就可以了,即只需要用key in dict
操作
- 创建:
- 直接使用花括号创建,如dict = {‘B’: 9, ‘C’:10}
- dict.fromkeys(seq [, value]):以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值创建字典
- dict.keys():返回一个迭代器,可以使用 list() 来转换为列表
- 访问:
- 使用[]通过键来访问值,如dict[‘B’]
- dict.get(key, default=None):返回指定键的值,如果值不在字典中返回default值
- dict.keys():返回字典的所有键。Python2中返回的是 list 类型,可使用索引获取其元素;而Python3中返回的是 dict_keys 类型,它是键的动态视图,即字典键发生变化时 dict_keys 对象也会发生改变,使用索引时可先用 list() 方法将其转为列表
- dict.values():返回字典的所有值。Python2中返回的是 list 类型,可使用索引获取其元素;同理Python3中返回的是动态视图 dict_values 类型,可先用 list() 方法将其转为列表
- dict.items():返回字典的所有键值对。Python2中返回的是以键值对元组为元素的列表;而Python3中返回的是动态视图 dict_items 类型,可先用 list() 方法将其转为列表
- 更新:
- 直接增加一个键值对,如dict[‘A’] = 8。若字典中已存在键,则更新值;若不存在,则添加键值对
- dict.setdefault(key, default=None):和get()类似,但如果键不存在则添加键并将值设为 default
- dict1.update(dict2):把字典dict2的键值对更新到dict1里
- 删除:
- del:使用 del 删除一个键值对,如del dict[‘A’];或直接删除整个字典,如del dict
- dict.pop(key [,default]):删除字典中键 key 所对应的值,返回值为被删除的值。当字典中不存在键key时,则返回default值
- dict.popitem():字典非空时返回并删除字典中的最后一个键值对
- dict.clear():使用clear()方法清空字典
- 其他:
- len(dict):返回字典中键值对的个数
【Python】第二章 内置数据类型相关推荐
- 学Python,这些内置数据类型总结(数字类型)你可否知道
数据类型是一种值的集合以及定义在这种值上的一组操作.一切语言的基础都是数据结构,所以打好基础对于后面的学习会有百利而无一害的作用. python内置的常用数据类型有:数字.字符串.Bytes.列表.元 ...
- Python中的内置数据类型
文章目录 列表 list 列表的嵌套使用 列表的特性 索引 index 切片 slide 重复 repeat 连接 link 成员操作符 迭代 列表元素的添加 普通方法: 追加 扩展 插入 列表元素的 ...
- python类型-Python基本内置数据类型有哪些?
玩蛇网Python学习平台在这里会和大家讲下Python初学者,最常用到的Python基本内置数据类型有哪些. 在Python程序中,每个数据都是对像,每个对像都有自己的一个类型.不同类型有不同的操作 ...
- Python数据结构与算法(1.2)——Python基础之变量与内置数据类型
Python数据结构与算法(1.2)--Python基础之变量与内置数据类型 0. 学习目标 1. Python 程序的运行 1.1 Python 交互式解释器 1.2 Python 程序脚本 2. ...
- python数据类型与数据结构--内置数据类型
学习目标:将python所涉及的数据类型.数据结构弄清楚 python作为面向对象编程语言.那么代表数据的对象都有哪些呢? 在这里我把他们分为内置数据类型,文件数据类型,第三方常用数据结构和自定义的数 ...
- 数据结构(Python版):Python内置数据类型
1. Python内置数据类型 python内置数据类型中的列表list和字典dict,可作为Python语言中实现各种常用数据结构的基石,后续各种数据结构均基于他们实现.两种数据类型的常见(操作)方 ...
- 以下不是python内置数据类型的是_以下不是python内置数据类型的是
以下不是python内置数据类型的是 答:float 关于分娩先兆,下述哪项是错误的 答:初产妇见红血量比经产妇多 中国提出的________理念,为世界和平繁荣提供了新路径,并被写入联合国决议 答: ...
- python3字典升序排序_python3从零学习-4.2、内置数据类型
内置标准类型: * Boolean(布尔) * Number(数字) * String(字符串) * List(列表) * Tuple(元组) * Sets(集合) * Dictionary(字典) ...
- 简学Python第二章__巧学数据结构文件操作
Python第二章__巧学数据结构文件操作 欢迎加入Linux_Python学习群 群号:478616847 目录: 列表 元祖 索引 字典 序列 文件操作 编码与文件方法 本站开始将引入一个新的概 ...
最新文章
- Ural 1018 (树形DP+背包+优化)
- Spring Security实现登录权限控制,记住我等功能
- python合并excel文件关键字_使用 Python 合并多个格式一致的 Excel 文件,Excel 表格...
- Fiddler抓取APP网络请求
- 2018ACM/ICPC亚洲区域赛(焦作)F. Honeycomb
- 【面向对象】聚合的四种语义
- 关于Image创建的内存管理
- 什么是函数模板以及什么是类模板
- java 关闭阻塞线程池_如果优雅地关闭ExecutorService提供的java线程池
- Struts2→MCV、环境搭建第一个样例、工作原理、核心文件、XML中常用元素、通配符、action后缀、action接收参数、result、标签
- SylixOS armv8 任务切换
- 大量的linux、H3C、cisco、华为、模拟器、adobe教程
- oracle wallet使用与维护---oracle无密码登录
- 一文读懂!最新Transformer预训练模型综述!
- DevOps 在公司项目中的实践落地
- 亚马逊AWS EC212个月免费计划及连接问题
- ORA-01653: 表 xxx 无法通过 (在表空间 xxx 中) 扩展
- jvm-10 垃圾回收3-垃圾回收器
- python拼图游戏代码的理解_Python编写的数字拼图游戏(含爬山算法人机对战功能)...
- 蓝牙信标有哪些附加功能?蓝牙信标的工业用途知多少?