Python3 中有六个标准的数据类型:Number(数字)、String(字符串)、List(列表)、Tuple(元组)、Set(集合)、Dictionary(字典)
Number(数字) 数字类型不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
Python3 有3中数值类型:整型int、浮点型float、复数complex。
其中,python3的整型没有限制大小,可以当作Long类型使用,且布尔bool是整型的子类型
| int | float | complex |
|---|---|---|
| 10 | 0.0 | 3.14j |
| 2147483600 | 15.20 | 45.j |
| -123 | -233.33 | 0.87e-36j |
| -0x260(0x表示是十六进制数) | 32e100 | 3e+6J |
| 0o37(0o表示是八进制) | 70…2E-2 | |
| 90. | -.23+0j | |
| 3.2e+18 | .876j |
>>> a, b, c = 23, 45.823, 2147483600 >>> print(type(a), type(b), type(c))算数运算符>>> d, e = True, False >>> type(d) >>> type(e) >>> f = 5+2j >>> type(f) >>> print(a, b, c, d, e, f) 23 45.823 2147483600 True False (5+2j) >>> num = 0xAF1 >>> num 2801 >>> num2 = 0o63 >>> num2 51
| 运算符 | 操作 | 例子(表达式=值) |
|---|---|---|
| + | 加 | 2+3=5 |
| - | 减 | 7-2=5 |
| * | 乘 | 3*2=6 |
| / | 除 | 22/8=2.75 |
| % | 取模/取余数 | 22%8=6 |
| // | 整除/商数取整 | 22//8=2 |
| ** | 指数 | 2**3=8 |
>>> 2 + 3 5 >>> 5-2 3 >>> 3 * 4 12 >>> 22 / 8 2.75 >>> 55 % 6 1 >>> 3**3 27 >>> 3**3 + 4 31 >>> 3 * (3+5) 24
在Python3 中,bool 是 int 的子类,True 和 False 可以和数字相加, True == 1、False == 0 会返回 True
>>> issubclass(bool, int) True >>> True == 1 True >>> False == 0 True >>> True + 3 4 >>> False + 3 3 >>> (3==3) +1 2类型转换
| 方法 | 描述 |
|---|---|
| int(x) | 将x转换为整数 |
| float(x) | 将x转换为浮点数 |
| complex(x[, y]) | 转为附属,实数部分为x,虚数部分为y,y默认为0,结果为x+yj |
>>> int(23.45)
23
>>> int("-3")
-3
>>> int(-4.777)
-4
>>> int("0x22")
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '0x22'
>>> int("23.45")
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '23.45'
>>> float(2)
2.0
>>> float("5.785")
5.785
>>> num = float("-4.55")
>>> type(num)
>>> num
-4.55
>>> float("12e-1")
1.2
>>> float("23de")
Traceback (most recent call last):
File "", line 1, in
ValueError: could not convert string to float: '23de'
>>> num = complex(3)
>>> num
(3+0j)
>>> type(num)
>>> complex(0, -4)
-4j
数学函数
| 函数 | 描述 |
|---|---|
| abs(x) | 内置函数,返回x的绝对值,返回的数值类型可能是整数值或浮点值(float或int类型)) |
| fabs(x) | math库的,返回x的绝对值,返回浮点值(float类型)) |
| ceil(x) | 返回数字的上入整数 |
| floor(x) | 返回数字的下舍整数 |
| max(x1, x2, …) | 返回给定参数中的最大值 |
| min(x1, x2, …) | 返回给定参数中的最小值 |
| pow(x, y) | 相当于x**y |
| round(x [,n]) | 返回浮点数x的四舍五入的值,n指定了小数点的位数(该函数近似于四舍五入,但实际上是保留值将保留到离上一位更近的一端) |
>>> abs(-2.3) 2.3 >>> abs(-20) 20 >>> abs(17) 17 >>> import math >>> math.fabs(-3.5) 3.5 >>> math.fabs(34) 34.0 >>> math.ceil(4.3) 5 >>> math.floor(4.3) 4 >>> max(34, -52, 89.3, 73.5) 89.3 >>> min(34, -52, 89.3, 73.5) -52 >>> pow(4, 5) 1024 >>> round(3.49, 1) 3.5 >>> round(3.49) 3 # 机器是按照一串0和1来表达数值的,有些浮点数如果用0和1表示是无限位数的(即无限接近,是≈不是=),但机器保存数值的空间是有限制的,所以不是不限位的,机器是截断储存,有精度差。2.675被截断保存后,机器中实际存储的值更接近2.67而不是2.68,所以返回结果是2.67 >>> round(2.675, 2) 2.67 >>> math.sqrt(64) 8.0数学常量
| 常量 | 描述 |
|---|---|
| pi | 圆周率,一般以π来表示 |
| e | 自然常数 |
>>> import math >>> print(math.pi) 3.141592653589793 >>> print(type(math.pi))运算符>>> print(math.e) 2.718281828459045
对于数值类型和一些数据类型,还有其他运算符,具体可查看该博客:python运算符
String(字符串)1、使用英文双引号或英文单引号括起来的内容,被定义为字符串
2、如果有多行内容,除了使用换行符之外,还可以使用"““xxx””"来定义
>>> str1 = 'hello, world' >>> str2 = "hello,双引号" >>> str3 = """人生苦短,我用python! ... 毕业了 ... 金三银四""" >>> str3 '人生苦短,我用python!n毕业了n金三银四' >>> print(str3) 人生苦短,我用python! 毕业了 金三银四字符串索引
python字符串正索引从0开始表示首个字符,负索引从-1开始表示字符串末尾的字符
可以通过索引的方式获取字符串中指定位置的值
>>> str1 = 'hello,world!' >>> str1[1] 'e' >>> str1[-3] 'l'
切片注意:索引的方式同样适用于List(列表)、Tuple(元组),只是获取到的对象不一样,字符串是某个字符,列表和元组是某个元素
使用格式:变量名[begin, end, step]
begin:开始位置,默认为0
end:结束位置,默认为变量长度
step:步长,即间隔多少进行获取,默认为1
python一般采用的是前闭后开的策略,即前面的参数是被包含进去的,后面的参数是不被包含进去的,比如begin被包含进去,end是不被算进去
>>> str1 = 'hello,world!' >>> str1[::] 'hello,world!' >>> str1[3:8] 'lo,wo' >>> str1[3:10:2] 'l,ol' >>> str1[-1:-5] '' >>> str1[-5:-1] 'orld' >>> str1[-1:-5:-1] '!dlr'
转义字符和原生字符串定义r注意:切片的方式同样适用于List(列表)、Tuple(元组),只是获取到的对象不一样,字符串是获取到新的字符串,列表、元组是获取到新的列表、元组
1.在某个情况下,我们需要在字符串里包含"、'、、换行等操作,但是"、'是用来定义字符串的,所以可以使用转义字符将其设置成单纯的"或’而不会被python解释
2.如果想忽略掉字符串中所有特殊字符,可以使用r修饰字符串,r表示字符串中的内容只是单纯的字符,不需要被python解释
>>> str1 = 'I'm a studetn!' >>> print(str1) I'm a studetn! >>> path = "C:\py310\Lib" >>> print(path) C:py310Lib >>> say = r'我们是使用表示转义字符,用""表示是字符串' >>> print(say) 我们是使用表示转义字符,用""表示是字符串 >>> str1 = 'I'm a studetn!nAnd you?' >>> print(str1) I'm a studetn! And you?字符串常用操作 拼接
>>> str1 = "hello," >>> str2 = "world!" >>> print(str1 + str2) hello,world!in 和 not in
| 操作符 | 描述 |
|---|---|
| in | 如果字符串被包含,则返回True,否则返回False |
| not in | 如果字符串不被包含,则返回True,否则返回False |
>>> str1 = "hello,world!" >>> "ello" in str1 True >>> "Ello" in str1 False >>> "ello" not in str1 False >>> "Ello" not in str1 Truef-string
从python3.6引入的,以f修饰的字符串,字符串如果包含{xxx},就会以对应的变量的值进行替换
格式;str1 = f"xxx{已定义的变量名}xxx"
>>> length = 6
>>> width = 3
>>> result = f"长方形长{length}cm,宽{width}cm,周长是{2*(length+width)}cm"
>>> print(result)
长方形长6cm,宽3cm,周长是18cm
编码encode
使用格式:str.encode(encoding=‘UTF-8’,errors=‘strict’)
encoding – 要使用的编码,默认编码为 ‘utf-8’,常用类型有:utf-8,gb2312,cp936,gbk等
errors – 设置不同错误的处理方案。默认为 ‘strict’,意为编码错误引起一个UnicodeError。 其他可能得值有 ‘ignore’, ‘replace’, ‘xmlcharrefreplace’, ‘backslashreplace’ 以及通过 codecs.register_error() 注册的任何值。
>>> str1 = "人生苦短,我用python" >>> print(str1) 人生苦短,我用python >>> print(str1.encode(encoding="utf8")) b'xe4xbaxbaxe7x94x9fxe8x8bxa6xe7x9fxadxefxbcx8cxe6x88x91xe7x94xa8python' >>> print(str1.encode(encoding="gb2312")) b'xc8xcbxc9xfaxbfxe0xb6xccxa3xacxcexd2xd3xc3python'是否包含
| 方法 | 描述 |
|---|---|
| find(str, beg=0, end=len(string)) | 返回指定范围包含str字符串开始的位置,如果没有找到,则返回-1。如果想从末尾开始找,可以使用rfind() |
| index(str, beg=0, end=len(string)) | 与find方法类似,区别是如果没有找到,则返回报错。如果想从末尾开始找,可以使用rindex() |
| isdigit() | 字符串如果是纯数字则返回True,否则为False |
| isspace() | 如果字符串是纯空格,则返回True,否则为False |
>>> str1 = "人生苦短,我用python"
# find()和index()
>>> str1.find("用py",2)
6
>>> str1.find("Python")
-1
>>> str1.index("py", 2, 10)
7
>>> str1.index("Py")
Traceback (most recent call last):
File "", line 1, in
ValueError: substring not found
# isdigit()的使用
>>> num = "34465"
>>> num.isdigit()
True
>>> num = "344.65"
>>> num.isdigit()
False
# isspace()的使用
>>> str1 = " "
>>> str1.isspace()
True
>>> str1 = " t "
>>> str1.isspace()
True
>>> str1 = " n "
>>> str1.isspace()
True
>>> str1 = " 1 "
>>> str1.isspace()
False
split
使用格式:str1.split(str2=“”, num=str1.count(str))
str1表示是要被分割的字符串,str2是分割符,num表示分割次数
注意:字符串是不可变数据,所以并不是对str1指向的字符串进行分割,是返回新的字符串列表数据
>>> str1 = "I feel cool,it is amazing!"
>>> split_list1 = str1.split(" ")
>>> print(split_list1)
['I', 'feel', 'cool,it', 'is', 'amazing!']
>>> print(type(split_list1))
>>> split_list2 = str1.split("i", 2)
>>> print(split_list2)
['I feel cool,', 't ', 's amazing!']
大小写
| 方法 | 描述 |
|---|---|
| upper() | 将字符串中的字母全都大写 |
| lower() | 将字符串中的字母全都小写 |
>>> str1 = "Happy new year!" >>> print(str1.upper()) HAPPY NEW YEAR! >>> print(str1.lower()) happy new year!format()
format()可以格式化字符串内容,format()中可以传入多个参数,字符串使用format中的参数时,以{下标}读取format中指定位置(从0开始)的参数值,对字符串内容进行填充,如果不填下标,默认按照顺序读取
>>> name1 = "俄国"
>>> name2 = "乌克兰"
# 不设置指定位置,按默认顺序
>>> str1 = "{}和{}的战争,{}的优势比较大".format(name1, name2, name1)
>>> print(str1)
俄国和乌克兰的战争,俄国的优势比较大
# 设置指定位置
>>> str2 = "{0}和{1}的战争,{0}的优势比较大".format(name1, name2)
>>> print(str2)
俄国和乌克兰的战争,俄国的优势比较大
# 通过名称传递变量
>>> str3 = "{country1}和{country2}的战争,{country1}的优势比较大".format(country1=name1, country2=name2)
>>> str3
'俄国和乌克兰的战争,俄国的优势比较大'
len()
len(str):返回字符串长度。默认情况下, len() 不区分英文、数字、汉字等字符,每个字符长度为1
如果想获取字符串的字节数,可以配合encode()来进行使用
>>> str1 = "人生苦短,我用python"
>>> len(str1)
13
>>> len(str1.encode())
27
>>> len(str1.encode("GBK"))
20
join()
格式:str.join(seq)
描述:将字符串序列seq以str为连接符进行连接,返回一个连接后的字符串
str:连接符
seq:字符串序列,可以时列表、元组等序列的数据类型。注意:列表或元组的元素必须是字符串类型
# 列表或元组的元素必须是字符串类型 >>> scores = ["wen", 27, "女", [87, 65, 23]] >>> ",".join(scores) Traceback (most recent call last): File "replace()", line 1, in TypeError: sequence item 1: expected str instance, int found >>> list1 = ["we", "learn", "python"] >>> " ".join(list1) 'we learn python' >>> file_name = ["姓名", "所在部门", "绩效综合考评表.xlsx"] >>> "_*".join(file_name) '姓名_*所在部门_*绩效综合考评表.xlsx'
格式:str.replace(old, new [, max])
把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
>>> content = "hurry up! hurry up, or we will be late"
>>> new_content = content.replace("hurry", "get")
>>> new_content
'get up! get up, or we will be late'
>>> content
'hurry up! hurry up, or we will be late'
strip()
去掉开头和末尾的空格(中间的空格不处理)
| 方法 | 描述 |
|---|---|
| lstrip() | 将字符串前面的空格去掉,返回新的字符串 |
| rstrip() | 将字符串末尾的空格去掉,返回新的字符串 |
| strip() | 将字符串前面和末尾的空格去掉,返回新的字符串,相当于执行了lstrip()和rstrip() |
>>> str1 = " t月有阴晴 圆缺t " >>> l_str1 = str1.lstrip() >>> l_str1 '月有阴晴 圆缺t ' >>> r_str1 = str1.rstrip() >>> r_str1 ' t月有阴晴 圆缺' >>> a_str1 = str1.strip() >>> a_str1 '月有阴晴 圆缺'List(列表)
列表是经常被用到的数据类型,其元素可以是数字,字符串、列表、元组、元素等或自定义类对象,列表是以[] 定义、用英文逗号分隔开的元素的集合,元素可以是重复的。
索引列表的索引与字符串类似,字符串是字符组成,而列表的索引是元素
>>> scores = ["wen", 27, "女", [87, 65, 23]] >>> scores[0] 'wen' >>> scores[-1] [87, 65, 23] >>> scores[1] 27 >>> scores[-1][1] 65切片
列表的切片与字符串一致,可以去看字符串的切片,这里就不重复了
>>> scores = ["wen", 27, "女", [87, 65, 23]] >>> scores[1:3] [27, '女'] >>> scores[-1::-1] [[87, 65, 23], '女', 27, 'wen']in 和 not in
判断某个值是否与列表的某个元素一致。使用in时,一致则返回True,否则返回False(注意:是列表的某个元素,不是元素中的包含关系),使用not in 时,一致返回False,没有一致的元素则返回True
>>> scores = ["wen", 27, "女", [87, 65, 23]] >>> "wen" in scores True >>> "we" in scores False >>> "we" not in scores Truelen()
返回列表元素数量
>>> scores = ["wen", 27, "女", [87, 65, 23]] >>> len(scores) 4 >>> len(scores[-1]) 3 >>> len(scores[0]) 3操作符+和*
| 操作符 | 描述 |
|---|---|
| + | 将列表连接,返回新的列表 |
| * | 将列表重复指定次数,返回新的列表 |
>>> scores = ["wen", 27, "女", [87, 65, 23]] >>> conten = ["语文:偏科严重", "数学:优秀!", "英语:希望继续努力"] >>> print(scores + conten) ['wen', 27, '女', [87, 65, 23], '语文:偏科严重', '数学:优秀!', '英语:希望继续努力'] >>> print(scores * 3) ['wen', 27, '女', [87, 65, 23], 'wen', 27, '女', [87, 65, 23], 'wen', 27, '女', [87, 65, 23]]添加元素
| 方法 | 描述 |
|---|---|
| append(obj) | 追加元素到列表中,即在列表末尾增加一个指定元素 |
| extend(iterable) | 追加多个元素到列表中,即在列表末尾增加多个元素,iterable是序列,表示要添加的元素序列 |
| insert(index, obj) | 在列表指定位置插入元素(指定位置及之后的元素都向后移动一个下标) |
>>> scores = [67, 39, 87, 93, 74, 65] >>> scores [67, 39, 87, 93, 74, 65] >>> scores.append(80.5) >>> scores [67, 39, 87, 93, 74, 65, 80.5] >>> scores.append([57, 44]) >>> scores [67, 39, 87, 93, 74, 65, 80.5, [57, 44]] >>> scores.extend([59, 48]) >>> scores [67, 39, 87, 93, 74, 65, 80.5, [57, 44], 59, 48] >>> scores.insert(3, "wen") >>> scores [67, 39, 87, 'wen', 93, 74, 65, 80.5, [57, 44], 59, 48]删除元素
| 方法 | 描述 |
|---|---|
| pop(index) | 删除并返回列表中指定索引的元素,index默认为-1,即最后一个元素 |
| remove() | 删除第一个与指定值匹配一致的元素(不会返回相关值) |
| del | 删除列表元素或整个列表 |
| clear() | 删除列表中所有元素,即成功后,列表是个空列表 |
>>> list1 = [23, 45, 58, 83, 45, 67, 59, 90, 100, 46] >>> value1 = list1.pop() >>> value1 46 >>> list1 [23, 45, 58, 83, 45, 67, 59, 90, 100] >>> value2 = list1.pop(5) >>> value2 67 >>> list1 [23, 45, 58, 83, 45, 59, 90, 100] >>> value3 = list1.remove(45) >>> value3 >>> list1 [23, 58, 83, 45, 59, 90, 100] >>> del list1[2] >>> list1 [23, 58, 45, 59, 90, 100] >>> list1.clear() >>> list1 [] >>> del list1 >>> list1 Traceback (most recent call last): File "修改元素", line 1, in NameError: name 'list1' is not defined. Did you mean: 'list'?
直接指定下标修改元素(注意:通过切片赋值时,赋值的列表个数必须与切片查询出来的元素个数保持一致!)
>>> list1 = [23, 45, 58, 83, 45, 67, 59, 90, 100, 46] # 单个下标赋值 >>> list1[-2] = "99" >>> list1 [23, 45, 58, 83, 45, 67, 59, 90, '99', 46] # 切片赋值 >>> list1[::2] [23, 58, 45, 59, '99'] >>> list1[::2] = [233, 588, 455, 599, 999] >>> list1 [233, 45, 588, 83, 455, 67, 599, 90, 999, 46] # 赋值个数与切片查询数量不一致时,报错 >>> list1[::2] = [23, 548, 45, 59] Traceback (most recent call last): File "查询元素", line 1, in ValueError: attempt to assign sequence of size 4 to extended slice of size 5 >>> list1[::2] = [23, 548, 45, 59, 1, 1] Traceback (most recent call last): File " ", line 1, in ValueError: attempt to assign sequence of size 6 to extended slice of size 5 >>> list1 [233, 45, 588, 83, 455, 67, 599, 90, 999, 46]
| 方法 | 描述 |
|---|---|
| index(obj) | 从列表中找出与指定值第一个匹配项的索引位置 |
| count(obj) | 统计某个元素在列表中出现的次数 |
>>> list1 = [34, 45, 29, 68, 91, 77, 29, 37, 29, 77] >>> list1.index(29) 2 >>> list1.count(29) 3 >>> list1.count(77) 2排序sort和反转reverse
格式:list.sort(key=None, reverse=False)
key – 指定带有一个参数的函数,用于从列表中的元素提取比较键
reverse – 排序规则,reverse = True 降序, reverse = False 升序(默认)。
>>> list1 [34, 45, 29, 68, 91, 77, 29, 37, 29, 77] # sort()默认升序排序 >>> list1.sort() >>> list1 [29, 29, 29, 34, 37, 45, 68, 77, 77, 91] # sort()设置降序排序 >>> list1.sort(reverse=True) >>> list1 [91, 77, 77, 68, 45, 37, 34, 29, 29, 29] # reverse()反转元素 >>> list1.reverse() >>> list1 [29, 29, 29, 34, 37, 45, 68, 77, 77, 91]
sort其他用法:
# 按照总分成绩降序排名
list1 = [[97, 54, 93], [59, 78, 83], [44, 64, 97], [83, 79, 73]]
def sum_scores(scores):
return scores[0] + scores[1] + scores[2]
list1.sort(key=sum_scores, reverse=True)
print(list1)
运行结果:
[[97, 54, 93], [83, 79, 73], [59, 78, 83], [44, 64, 97]]
根据元组、字符串等序列转成并列表(不会修改原有的序列)
>>> tup1 = (34, 79, 28) >>> list_from_tup = list(tup1) >>> list_from_tup [34, 79, 28] >>> tup1 (34, 79, 28) >>> str1 = "we make it!" >>> str_list = list(str1) >>> str_list ['w', 'e', ' ', 'm', 'a', 'k', 'e', ' ', 'i', 't', '!']Tuple(元组)
Python 的元组与列表类似,但元组的元素不能修改(列表可以)。
元组使用小括号 ( )来定义,元素间使用英文逗号隔开
元组中只包含一个元素时,需要在元素后面添加逗号 ,否则括号会被当作运算符使用。
# 空元组 >>> t1 = () >>> type(t1)切片# 元组中只包含一个元素时,需要在元素后面添加逗号 ,否则括号会被当作运算符使用。 >>> t1 = ("23") >>> type(t1) >>> t1 = ("23",) >>> type(t1) >>> tup = 1, 2, 3 >>> tup (1, 2, 3) >>> a, b, c = tup >>> print(a, b, c) 1 2 3
元组的切片与列表一致,只是不能根据切片来修改元素
>>> tuple1 = (23, 56, 93, 75, 66) >>> tuple1[1] 56 >>> tuple1[-1] 66 >>> tuple1[1:3] (56, 93) >>> tuple1[1::-1] (56, 23)len()
len()可以计算出元组的元素个数
>>> tuple1 = (23, 56, 93, 75, 66) >>> len(tuple1) 5in 和 not in
逻辑与列表的使用逻辑一致,若内容与元组的某个元素一致,in则返回True,无一致的则返回False,not in 与in相反
>>> t1 = (23, "67", "53", 77) >>> 77 in t1 True >>> "5" in t1 False >>> 77 not in t1 False >>> "45" not in t1 True操作符+和*
| 操作符 | 描述 |
|---|---|
| + | 将元组的元素合并成一个新的元组 |
| * | 将某个元组的内容重复多次,生成一个新的元组 |
# 合并元组成新元组
>>> t1 = (23, "67")
>>> t2 = ("53", 79)
>>> t3 = t1 + t2
>>> t3
(23, '67', '53', 79)
# 重复元组元素生成新的元组
>>> t4 = t1 * 3
>>> t4
(23, '67', 23, '67', 23, '67')
tuple()
tuple(iterable):将可迭代系列转换为元组。
>>> l1 = [45, 26, "33"] >>> t1 = tuple(l1) >>> t1 (45, 26, '33') >>> type(t1)index()和count()>>> t2 = tuple("python") >>> t2 ('p', 'y', 't', 'h', 'o', 'n')
| 方法 | 描述 |
|---|---|
| index(obj) | 从元组中找出与指定值第一个匹配项的索引位置,元组中无匹配的则报错,使用前最好跟in使用 |
| count(obj) | 统计某个元素在元组中出现的次数 |
>>> tup1 = ("wen", "hello", "world", 22, 67, [34, 67], "hello", 22, 67)
>>> tup1.index("hello")
1
>>> tup1.index(22)
3
>>> tup1.index(34)
Traceback (most recent call last):
File "", line 1, in
ValueError: tuple.index(x): x not in tuple
>>> tup1.count("hello")
2
>>> tup1.count("Wen")
0
关于元组不可变
前面说过元组的元素是不可变的,这个不可变指的是内存中的内存,对于不可变的变量来说,其赋值后,变量所在地址存储的是变量的值,对于可变的变量来说,变量所在地址存储的是对象的内存地址,即不是对象的值,是“内存地址”,所以如果元组中的元素是某个对象时,会发现修改该对象的某个成员变量是可以的,因为修改对象的内容时,对象的内存地址未变,所以并没有修改到元组中元素的值(内存地址),具体的内容后面会更新
>>> list1 = [23, 56] >>> id(list1) 1941230715072 >>> id(list1[0]) 1941225341872 >>> id(list[1]) 1941230964288 >>> t1 = (34, 555, list1, "hha") # id(t1[2]) 可以看出,元组t1存放的是list1的内存地址(不是list1变量) >>> id(t1[2]) 1941230715072 # 修改list1的元素并没有修改变量的内存地址 # 即元组t1和列表list1的内存地址没有被改动,改动的只是地址指向的内容 >>> list1[0] = 96 >>> id(list1) 1941230715072 >>> id(list1[0]) 1941225344208 >>> t1 (34, 555, [96, 56], 'hha') >>> id(t1[2]) 1941230715072Set(集合)
集合(set)是一个无序的不重复元素序列。
使用大括号 { } 或者 set() 函数来创建集合,
如果想创建一个空集合必须用 set() ( { } 是用来创建一个空字典的)。
注意:集合只存储不可变的数据类型,如Number(数字)、字符串、元组等,而无法存储列表、字典、集合这些可变的数据类型
# 通过{}创建集合
>>> set1 = {"v1", "V2", 34, 34, "v2"}
>>> set1
{34, 'v1', 'v2', 'V2'}
# 通过set(value)创建集合,传入的value是类似列表的可迭代对象,或者是字符串
>>> set2 = set([23, "abc", "23", "abc"])
>>> set2
{'23', 'abc', 23}
>>> set3 = set("wen")
>>> set3
{'w', 'e', 'n'}
>>> set4 = set(23, 35)
Traceback (most recent call last):
File "", line 1, in
TypeError: set expected at most 1 argument, got 2
# set的元素只能是不可变的数据类型
>>> set5 = {23, "45", (34, 78), 78, "45"}
>>> print(type(set5), set5)
{'45', (34, 78), 78, 23}
>>> set6 = {23, [34, 67]}
Traceback (most recent call last):
File "", line 1, in
TypeError: unhashable type: 'list'
集合的操作符
| 操作符 | 描述 |
|---|---|
| - | 差集,即去掉集合中在另一个集合中也存在的元素 |
| & | 交集,取在两个集合中都存在的元素 |
| | | 并集,集合合并(并去重)后的全部元素 |
| ^ | 对称差集,即集合去掉在两个集合中都存在的元素后合并的元素,即集合A|集合B - A&B |
>>> a = {11, 22, 33}
>>> b = {33, 44, 55}
>
>>> a-b
{11, 22}
>>> b-a
{44, 55}
>>> a&b
{33}
>>> a|b
{33, 22, 55, 11, 44}
>>> a^b
{11, 44, 22, 55}
集合也有类似的方法来实现集合的操作
| 方法 | 描述 |
|---|---|
| set1.difference(set2) | 返回集合的差集,即返回的集合元素包含在set1中,但不包含在set2中 |
| set1.intersection(set2, set3 … setn) | 返回两个或更多集合中都包含的元素,即多个集合的交集 |
| set1.union(set2, set3…, setn) | 返回两个或多个集合的并集,即包含了所有集合的元素(元素不重复) |
| set1.symmetric_difference_update(set2) | 类似于对称差集,即执行了^(直接对set1生效,只有1个参数,返回None) |
>>> set1 = {11, 22, 33}
>>> set2 = {33, 44, 55}
>>> set3 = {33, 22, 44, 66, 77}
# difference()
>>> set4 = set1.difference(set2, set3)
>>> set4
{11}
# intersection()
>>> set5 = set2.intersection(set1, set3)
>>> set5
{33}
>>> set6 = set3.intersection(set2)
>>> set6
{33, 44}
# union()
>>> set7 = set1.union(set2, set3)
>>> set7
{33, 66, 11, 44, 77, 22, 55}
# symmetric_difference_update()
# 多个参数时报错
>>> set8 = set1.symmetric_difference_update(set2, set3)
Traceback (most recent call last):
File "", line 1, in
TypeError: set.symmetric_difference_update() takes exactly one argument (2 given)
# 只能传入一个参数,直接对原集合进行操作,不会返回内容,即返回None
>>> set8 = set1.symmetric_difference_update(set2)
>>> set8
>>> set1
{11, 44, 22, 55}
添加元素
| 函数 | 描述 |
|---|---|
| s.add(x) | 将元素添加到集合s中,若元素在集合s中已存在,则不进行任何操作 |
| s.update(x) | 批量添加可迭代对象(iterable)x中的所有元素到集合s中,参数x可以是列表、元组、字典等 |
>>> set1 = set([12, 34, 76, 45])
>>> set1
{34, 12, 45, 76}
>>> set1.add("wen")
>>> set1
{34, 12, 45, 76, 'wen'}
>>> set1.add(45)
>>> set1
{34, 12, 45, 76, 'wen'}
# update(x)中的参数x如果是多个,可以用逗号分隔开
>>> set1.update("wfef")
>>> set1
{34, 'f', 12, 45, 76, 'e', 'w', 'wen'}
>>> set1.update([12, 44])
>>> set1
{34, 'f', 12, 45, 76, 'e', 44, 'w', 'wen'}
>>>
>>> set1.update((56, 76), ('add', 'wen1'))
>>> set1
{34, 'f', 'add', 12, 45, 76, 'e', 44, 'w', 56, 'wen', 'wen1'}
移除元素
| 函数 | 描述 |
|---|---|
| s.remove(x) | 将元素x从集合s中移除,若元素在集合s中不存在,则报错,可以配合in使用 |
| s.discard(x) | 将元素x从集合s中移除,若元素在集合s中不存在也不会报错 |
| s.pop() | 随机删除集合中的一个元素,并返回元素 |
| s.clear() | 清空集合s,结果是s变成了空集合 |
>>> set1
{'+', 'add', '+=', 'extend', 'sum', 'attend'}
# remove()
>>> set1.remove("+=")
>>> set1
{'+', 'add', 'extend', 'sum', 'attend'}
>>> set1.remove("+=")
Traceback (most recent call last):
File "", line 1, in
KeyError: '+='
# discard()
>>> set1.discard("+")
>>> set1
{'add', 'extend', 'sum', 'attend'}
>>> set1.discard("+")
>>> set1
{'add', 'extend', 'sum', 'attend'}
# pop()
>>> set1.pop()
'add'
>>> set1.pop()
'extend'
>>> set1
{'sum', 'attend'}
# clear()
>>> set1.clear()
>>> print(type(set1), len(set1), set1)
0 set()
计算元素个数len()
语法:len(s):s为集合
>>> set1 = set()
>>> len(set1)
0
>>> set2 = {45, 23, 35, "wen"}
>>> len(set2)
4
in 和 not in
使用方法与列表的一致
| 操作符 | 描述 |
|---|---|
| in | 如果元素在集合中存在则返回True,否则返回False |
| not in | 如果元素在集合中不存在,则返回True,否则返回False |
>>> set2
{'wen', 35, 45, 23}
>>> 35 in set2
True
>>> "we" in set2
False
>>> "we" not in set2
True
>>> "wen" not in set2
False
子集判断
| 操作符 | 描述 |
|---|---|
| set1.issubset(set2) | 判断set1是否为set2的子集,为set2的子集时返回True,否则返回False |
| set1…issuperset(set2) | 判断set2是否为set1的子集,如果set2是set1的子集,返回True,否则返回False |
# 判断是否时某个集合的子集
>>> set1
{'wen', 45}
>>> set1.issubset({'wen', 35, 45, 23})
True
>>> set1.issubset({'Wen', 35, 45, 23})
False
# 判断是否为某个集合的父集
>>> {'wen', 35, 45, 23}.issuperset(set1)
True
>>> {'Wen', 35, 45, 23}.issuperset(set1)
False
Dictionary(字典)
字典是python中经常用到的数据类型。字典以键值对(key: value)的方式存储对象
字典定义格式:{key1 : value1, key2 : value2, key3 : value3 }
1、键(key)和值(value)之间以英文冒号:连接,每个键值对之间使用英文逗号,分割,整个字典在{}中
2、键(key)在字典中必须是唯一的,且键是不可变的数据类型,如字符串、数字、元组。如果创建时键被赋值多次,最后一个值会被记住
3、值(value)可以是任意对象,比如None、数值、字符串、字典等
# 空字典 >>> empt_dict = dict() >>> print(len(empt_dict), type(empt_dict)) 0查询和遍历>>> ed = {} >>> print(len(ed), type(ed)) 0 # 字典定义 >>> d1 = {"eng_name": "csdn", "chn_name": "博客", "age": 34, "scores": {"english": 78, "math": 97, "chinese": 88}, 123: "rt"} >>> d1 {'eng_name': 'csdn', 'chn_name': '博客', 'age': 34, 'scores': {'english': 78, 'math': 97, 'chinese': 88}, 123: 'rt'} # 如果创建时键被赋值多次,最后一个值会被记住 >>> d2 = {"k1": "v1", "k2": "v2", "k1": "v2"} >>> d2 {'k1': 'v2', 'k2': 'v2'} # dict()定义字典 >>> d3 = dict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')]) >>> d3 {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
| 使用格式 | 描述 |
|---|---|
| dict[key] | 根据键名获取对应的值,如果键不在字典中,则会报错(KeyError) |
| dict.get(key, default=None) | 返回指定键的值,如果键不在字典中返回 default 设置的默认值 |
| dict.items() | 返回动态的键值对视图对象(视图对象不是列表,可用list()转为列表,字典的视图对象都是只读的,不可修改) |
| dict.keys() | 返回动态的键视图对象 |
| dict.values() | 返回动态的值视图对象 |
| dict.setdefault(key, default=None) | 如果key在字典中存在,则返回字典中的值,如果key不在字典中,则给字典添加键值对(键为key,值为default的值) |
注:“动态的”指随着原对象的变更而变更
>>> dt = {"k1": "v1", "k2": "v2", "k3": "v3"}
>>> dt["k2"]
'v2'
>>> dt["k4"]
Traceback (most recent call last):
File "", line 1, in
KeyError: 'k4'
# get()
>>> dt.get("k3", 23)
'v3'
>>> dt.get("k4")
>>> dt.get("k4", 56)
56
# items()
>>> res = dt.items()
>>> print(type(res), res)
dict_items([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
>>> keys = dt.keys()
>>> keys
dict_keys(['k1', 'k2', 'k3'])
>>> values = dt.values()
>>> values
dict_values(['v1', 'v2', 'v3'])
# 通过for循环遍历字典并进行修改
>>> for k, v in dt.items():
... dt[k] = str(v) + "_end"
...
>>> dt
{'k1': 'v1_end', 'k2': 'v2_end', 'k3': 'v3_end'}
# items()、keys()、values()获取的是字典的动态视图,即字典更新,相关内容也随着更新
>>> res
dict_items([('k1', 'v1_end'), ('k2', 'v2_end'), ('k3', 'v3_end')])
>>> keys
dict_keys(['k1', 'k2', 'k3'])
>>> values
dict_values(['v1_end', 'v2_end', 'v3_end'])
# 对于嵌套字典,查询方式也是嵌套思路来
>>> dt = {'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47]}
>>> dt['k2']
{'k22': 'v22', 'k23': 'v23'}
>>> dt['k2']['k23']
'v23'
>>> dt['k3'][1]
56
# setdefault()
# 如果key在字典中存在,则返回字典中的值
>>> dt = {'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47]}
>>> dt.setdefault('k1')
'v1'
>>> dt.setdefault('k1', 44)
'v1'
# setdefault()默认赋值为None
>>> dt.setdefault('k4')
>>> dt
{'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47], 'k4': None}
>>> dt.setdefault('k5', 54)
54
>>> dt
{'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47], 'k4': None, 'k5': 54}
修改字典
| 使用格式 | 描述 |
|---|---|
| dict[key] = new_value | 如果键在字典中,修改对应键名的值;如果键不在字典中,则添加键值对 |
| dict.setdefault(key, default=None) | 如果key在字典中存在,则返回字典中的值,如果key不在字典中,则给字典添加键值对(键为key,值为default的值),具体参考例子可以在当前的字典下的【查询和遍历】中查看 |
| dict.update(dict2) | 将字典dict2的键值对更新到dict里(dict里已有的键则更新值,没有的键则添加键值对),返回None |
>>> dt = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
# 键存在时,修改键对应的值
>>> dt['k2'] = 45
>>> dt
{'k1': 'v1', 'k2': 45, 'k3': 'v3'}
# 键不存在时,添加键值对
>>> dt['k4'] = 'you'
>>> dt
{'k1': 'v1', 'k2': 45, 'k3': 'v3', 'k4': 'you'}
# update()
>>> dt2 = {'k3': 56, 'k5': [45, 44]}
>>> dt.update(dt2)
>>> dt
{'k1': 'v1', 'k2': 45, 'k3': 56, 'k4': 'you', 'k5': [45, 44]}
# update只更新当前字典的键值对,不更新嵌套的字典,对于当前字典来说,嵌套字典只是某个键的值value,并不是键key,update()是根据当前字典的键key去更新的,不是根据值去更新的
>>> dt3 = {'k1': {'k3': 'when', 'k6': 'xxx'}, 'k3': 'how'}
>>> dt3.update(dt2)
>>> dt3
{'k1': {'k3': 'when', 'k6': 'xxx'}, 'k3': 56, 'k5': [45, 44]}
删除字典内容
| 使用格式 | 描述 |
|---|---|
| del dict[key] | 删除字典dict里的某个key的键值对 |
| del dict | 删除字典dict |
| dict.clear() | 清空字典dict(dict最后为空字典) |
| dict.pop(key[, default=None]) | 删除字典dict中的键为key的键值对,并返回被删除的键的值。若键不存在,则直接返回默认值default |
| dict.popitem() | 删除并返回字典dict中最后一对键值,若字典已为空字典,返回异常NameError |
>>> dt3
{'k1': {'k3': 'when', 'k6': 'xxx'}, 'k3': 56, 'k5': [45, 44]}
>>> del dt3['k1']['k3']
>>> dt3
{'k1': {'k6': 'xxx'}, 'k3': 56, 'k5': [45, 44]}
# pop()
>>> dt3.pop('k5', 'root')
[45, 44]
>>> dt3
{'k1': {'k6': 'xxx'}, 'k3': 56}
>>> dt3.pop('k5', 'root')
'root'
>>> dt3
{'k1': {'k6': 'xxx'}, 'k3': 56}
# popitem()
>>> dt3.popitem()
('k3', 56)
>>> dt3
{'k1': {'k6': 'xxx'}}
# clear()
>>> dt3.clear()
>>> print(type(dt3),len(dt3), dt3)
0 {}
# 空字典时,popitem()报错
>>> dt3.popitem()
Traceback (most recent call last):
File "", line 1, in
KeyError: 'popitem(): dictionary is empty'
# del删除字典
>>> del dt3
>>> dt3
Traceback (most recent call last):
File "", line 1, in
NameError: name 'dt3' is not defined. Did you mean: 'dt'?
复制或创建字典
| 使用格式 | 描述 |
|---|---|
| dict.copy() | 返回字典dict的浅拷贝 |
| copy.deepcopy(dict) | 返回字典dict的深拷贝 |
| dict.fromkeys(seq[, value=None]) | 以序列seq为键创建字典,键的值默认为value |
| 关于深拷贝和浅拷贝,请看当前页面的【其他内容】的【浅拷贝和深拷贝】章节,这里不进行赘述了 |
>>> score_seq = ('Englis', 'Chinese', 'Math', 'Music', 'Sport')
>>> dict.fromkeys(score_seq)
{'Englis': None, 'Chinese': None, 'Math': None, 'Music': None, 'Sport': None}
>>> dict.fromkeys(score_seq, 0)
{'Englis': 0, 'Chinese': 0, 'Math': 0, 'Music': 0, 'Sport': 0}
字典个数len()
计算字典元素个数,即键的总数(不包含嵌套的对象)
>>> dt
{'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47]}
>>> len(dt)
3
转成字符串str()
将字典对象dict转换成字符串
>>> dt
{'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47]}
>>> type(dt)
>>> str_dt = str(dt)
>>> print(type(str_dt), str_dt)
{'k1': 'v1', 'k2': {'k22': 'v22', 'k23': 'v23'}, 'k3': [23, 56, 47]}
in 和 not in
| 使用格式 | 描述 |
|---|---|
| key in dict | 判断字典是否存在键为key,存在返回True,不存在则返回False |
| key not in dict | 判断字典是否不存在键为key,不存在返回True,存在则返回False |
| 一般情况下,如果是需要遍历字典,in和not in是配合函数keys()、values()、items()使用的 |
>>> dt
{'k1': {'k6': 'xxx'}, 'k3': 56, 'k5': [45, 44]}
>>> 'k6' in dt
False
>>> 'k1' in dt
True
>>> 'k6' not in dt
True
>>> 'k1' not in dt
False
>>> for key, value in dt.items():
... print(str(key), " = ", str(value))
...
k1 = {'k6': 'xxx'}
k3 = 56
k5 = [45, 44]
其他内容
删除变量del
在python3中,所有的基本数据类型均有相关的类,当我们给某个变量赋值时,实际上创建了该种数据类型的实例(从type方法可以看出来,均为类calss),可以使用del删除变量
# 当你指定一个值时,相应对象就会被创建 >>> var1 = [1, 3] >>> a = 23 >>> print(type(var1), type(a))推导式>>> print(var1, a) [1, 3] 23 # 使用del方法删除变量后,访问变量就会报错 >>> del var1, a >>> var1 Traceback (most recent call last): File " ", line 1, in NameError: name 'var1' is not defined. Did you mean: 'vars'? >>> a Traceback (most recent call last): File " ", line 1, in NameError: name 'a' is not defined
推导式一般是针对列表、集合等迭代对象,有所称是:列表推导式、集合推导式等
列表推导式语法:[x for x in iterable if x …] 或 [fun(x) for x in iterable if x …]
集合推导式语法:{x for x in iterable if x …} 或 {fun(x) for x in iterable if x …}
字典推导式语法:{k: v for k, v in iterable if …} 或{fun(k, v) for k, v in iterable if …} (fun(k, v)必须只有2个返回值)
>>> list_1 = [ele for ele in range(0, 14) if ele % 2 == 0]
>>> print(list_1)
[0, 2, 4, 6, 8, 10, 12]
# 列表推导式
>>> list_str1 = ["hello", "world", "wen", "goodbye", "morning", "nice"]
>>> list_str2 = [ele for ele in list_str1 if len(ele)<6]
>>> list_str2
['hello', 'world', 'wen', 'nice']
>>> import math
>>> list_str3 = [math.pow(len(ele), 3) for ele in list_str1 if len(ele)<6]
>>> list_str3
[125.0, 125.0, 27.0, 64.0]
# 集合推导式
>>> set1 = {x for x in "yesterday" if x in "today is friday"}
>>> set1
{'y', 'd', 's', 't', 'a', 'r'}
# 字典推导式
>>> dt = {k: v for k, v in [("name", "Harry Potter"), ("age", 17)]}
>>> dt
{'name': 'Harry Potter', 'age': 17}
>>> dt = {k: v for k, v in[("English", 84), ("Chinese", 89), ("math", 66), ("other", 55)] if v <= 80}
>>> dt
{'math': 66, 'other': 55}
浅拷贝和深拷贝
python提供了列表、字典、集合等数据类型的浅拷贝和深拷贝方法。
| 函数 | 描述 |
|---|---|
| iterable.copy() | 返回可迭代对象iterable的浅拷贝数据 |
| copy.deepcopy(iterable) | 返回可迭代对象iterable的深拷贝数据 |
如果从相对简单的角度来理解的话,浅拷贝和深拷贝是针对嵌套对象的区别,对原数据的嵌套对象的修改,浅拷贝对应的嵌套对象会同步影响,深拷贝就不会受影响。
从存储的角度来理解,浅拷贝就是增加了指针指向值的存储地址,并没有对值开辟新的内存空间进行存储,深拷贝则是开辟新的内存空间去存储并指针指向新的内存地址。
浅拷贝说明
>>> dt = {'k1': 23, 'k2': [1, 45]}
>>> dt_c = dt.copy()
>>> dt['k1'] = 55
>>> dt
{'k1': 55, 'k2': [1, 45]}
>>> dt_c
{'k1': 23, 'k2': [1, 45]}
>>> dt['k2'][0] = "one"
>>> dt
{'k1': 55, 'k2': ['one', 45]}
>>> dt_c
{'k1': 23, 'k2': ['one', 45]}
程序说明:
在申明dt时,会根据数据开辟存储空间,从图中可以看出,23是int对象的内容,[1, 45]是list对象的内容
copy()方法只是增加了指向对象的指针,并没有分配新的空间去存储对象内容
dt[‘k1’]赋值为55时,系统创建了一个int对象(数值类型是不可变的数据类型,所以原数据不动,重新创建,而不是修改),对象内容为55,并将dt[‘k1’]指向这个新创建的int对象
dt[‘k2’][0]被重新赋值,这一操作只是新增了一个字符串对象,对象内容为"one",并将list对象的list[0]指向这个字符串对象,并没有生成新的list对象
如果想dt和dt_c的list对象不会相互影响,就需要将2者指向不同的list对象,如下操作(不建议这样,不如直接使用深拷贝):
>>> dt['k2'] = ['one', 45]
>>> dt
{'k1': 55, 'k2': ['one', 45]}
>>> dt_c
{'k1': 23, 'k2': ['one', 45]}
>>> dt['k2'][0] = 'two'
>>> dt
{'k1': 55, 'k2': ['two', 45]}
>>> dt_c
{'k1': 23, 'k2': ['one', 45]}
深拷贝说明
深拷贝直接将内容复制到另一个存储空间中,与原数据是分开的,所以原数据和深拷贝的数据是互不影响的
>>> dt = {'k1': 23, 'k2': [1, 45]}
>>> import copy
>>> dc = copy.deepcopy(dt)
>>> dt['k2'][0] = 'one'
>>> dt
{'k1': 23, 'k2': ['one', 45]}
>>> dc
{'k1': 23, 'k2': [1, 45]}



