【深度学习】Part1 Python学习基础Ch01~Ch06——DeepBlue学习

本文仅供学习参考,方便查阅相关命令

1 Python 与 编程语言

用来和计算机交流,控制计算机,让计算机按照我们的要求做事情,这样的语言叫做编程语言;用任何编程语言来开发程序,都是为了让计算机干活,而计算机干活的 CPU只认识机器指令,所以尽管不同的编程语言差异极大,最后都得“翻译”成CPU可以执行的机器指令

1.1 Python 语言的优缺点

Python是一种相当高级的语言(当然,C/C++、java也都是高级语言),也因此,对于大部分任务而言,Python语言的学习和使用是相对更简单的。代码少的代价是运行速度慢。
低级语言:汇编语言——CPU认识的机器指令—>C—>C++—>Java、Python

1.2 Python 环境搭建

直接安装 anaconda,它是一个开源的 Python 发行版本,其包含了conda、Python等180多个科学包及其依赖项。这样会比单独安装 Python,再去安装一堆的工具包更省事
anaconda 官方下载地址:
https://www.anaconda.com/products/individual anaconda
清华镜像下载地址(推荐):
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?C=M&O=D

1.3 IDE 安装

IDE(集成开发环境)来写代码——集成了代码编写、分析、编译、调试等一体化的开发软件服务,大大提升工作效率

Ctrl+D——退出命令
Exit——退出页面
Vscode:
选择解释器C+S+P:select
选择设置:update—>none

1. 4 Python 之禅(Zen of Python)

Python 之禅列出了 Python 设计的原则与哲学,有助于理解与使用这种语言。

• 优美胜于丑陋(Python 以编写优美的代码为目标)
• 明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
• 简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
• 复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
• 扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
• 间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
• 可读性很重要(优美的代码是可读的)
• 即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
• 不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写except:pass 风格的代码)
• 当存在多种可能,不要尝试去猜测• 而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
• 虽然这并不容易,因为你不是Python之父(这里的 Dutch是指作者Guido)
• 做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
• 如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
• 命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)

快捷键设置:在终端中运行python:S+E
Clear——清除对话框
C+E—>添加下一行

1.5 用 IDE 看语法、报错提示、调试

print(2 / 0) # 报错
ZeroDivisionError: division by zero

print(2 + "zhongguo") # 报错
TypeError: unsupported operand type(s) for +: 'int' and 'str'

调试——debug——F5
单步调试:
单步跳过:跳过函数内的单步调试,直接给出结果;
继续:端点之间进行运行调试;

print("执行第1行啦") 
print(2 / 1) # 报错 
print("执行第3行啦") 
a = 123 

def add(left, right): 
    print("执行第7行啦") 
    print("执行第8行啦", left + right) 

print("执行第10行啦") 
add(3, 4) 
a = 124 
print("执行第13行啦")       

上文内容仅供参考,非重点部分

2 基础语法

2.1 行结构

一个 Python 程序可分为许多逻辑行,一般来说:一个语句就是一行代码,不会跨越多行;
也可以把多个语句利用英文输入下的分号(;)写在一行之内,不过通常我们不这么做;
也有语句是可以跨越多行的,比如:复合语句。复合语句可由多行子语句组成,通常它会跨越多行;

a = 4
if a < 3:
	print(True)
else:
	print(False)

有的时候,整个复合语句也可能包含于一行之内——三元表达式:

a = 4
print(True) if a < 3 else print(False)

2.2 缩进

一个逻辑行开头处的空白被用来计算该行的缩进等级,以决定语句段落的组织结构。
在IDE中写程序时,需要缩进的语句,一般敲回车换行会自动缩进的,一般是占 4个空格,我们在写代码需要缩进时通常用Tab键,而不用按4次空格(Tab键一般可以把光标缩进4个空格,通常这是IDE可设置的)。

2.3 注释

注释在 Python 解释器的语法分析中会被忽略。通说的说,注释是给人看的,而程序执行时会被无视
单行注释:以 # 开头
多行注释:每行都用一个 # 开头,或者用 三引号(可单 ‘’’ 、可双”“”)把注释内容包起来
多选快速注释:C+?

print(1234)  
# 第一个注释 
# # 第二个注释 
''' 
第三个注释 三引号可以多行注释 
'''

"""" """
""" 
第四个注释 三引号可以多行注释
"""
print("Hello, Python!") # 第五个注释

2.4 拼接

显式的行拼接:Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠(\)来实现多行语句

a = 1 + 1 +\
3 + \
4 \
+ 5\
print(a)

隐式的行拼接:圆括号、方括号或花括号以内的多行语句,无需使用反斜杠(\)

month_names = ['Januari', 'Februari', 'Maart',  # These are the
               'April', 'Mei', 'Juni',  # Dutch names
               'Juli', 'Augustus', 'September',  # for the months
               'Oktober', 'November', 'December']  # of the year

2.5 变量

变量就是可以变化的量。是计算机语言中能储存计算结果或能表示值的抽象概念

变量需要先定义再使用,解释器执行到变量定义的代码时会申请内存空间存放变量值,然后将变量值的内存地址绑定给变量名

变量的定义由三部分组成:

  1. 变量名:指向值所在的内存地址,通过它访问值;
  2. 等于号(=):赋值符号,用来将变量的内存地址绑定给变量名;
  3. 值:变量的值就是内存地址对应存储的数据;

标识符:用于变量、函数、类、模块等的名称
标识符命名规范:

  1. 变量名只能包括字母、数字和下划线;变量名不能以数字开头
  2. 变量名不能包括空格,可以使用下划线来分隔多个单词
  3. 不能使用Python的关键字及内置函数名作变量名
  4. 变量名要尽量简短及具描述性,尽量做到短小精悍,见名知义
  5. Python中变量名是区分大小写的,例如Name和name是两个不同的变量名
  6. 可参考:驼峰命名法

关键字查询:

help("keywords")
import keyword 
print(keyword.kwlist)

import builtins 
print(dir(builtins))

内置函数:

  1. Python解释器内置了很多函数和类型,可以直接使用它们。以下按字母表顺序列出它们:
  2. 查看 Python 的内置函数:
import builtins 
print(dir(builtins))

2.6 常量

常量就是不变化的量。在程序运行过程中,有些值是固定的、不应该被改变,比如圆周率 3.141592653…
在 Python 中没有一个专门的语法定义常量,约定俗成是用全部大写的变量名表示常量。如:PI=3.14159
所以单从语法层面去讲,常量的使用与变量完全一致

3. 输入&输出

3.1 输出

print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)
· objects:输出的对象,输出多个对象时,需要用 , 分隔,对象会被转成字符串再输出(变长)
· sep:输出的对象用什么间隔开来,默认值是一个空格
· end:输出最后用什么结尾,默认值是换行符 \n
· file:要写入的文件对象,默认为sys.stdout,指向控制台
· flush:通常输出是否被缓存决定于 flush ,但如果 flush 关键字参数为 True,流会被强制刷新

print('Hello Python!')

with open('./abc.txt', 'w') as f:
	print(12345, file = f)  # 把12345写入 abc.txt文件

import time
print(1, 2, 3, seq = '-', end  = '\n\n')  # 把三个数字1,2,3转换成字符串写入,并用‘-’分隔,结尾换两行
print('Loading',end = '')
for i in range(10):
	print('.', end = ' ', flush = True)  
	# 如果flush为False,则为10次循环后终端显示结果
	# 如果flush为True,则为动态效果
	time.sleep(0.3)

3.2 输入

input([prompt])
prompt: 提示信息,string类型
函数接受一个标准输入数据,返回为string类型

[ ]代表可选信息(可不填)

4. 标准数据类型

Python 3 中有六个标准的数据类型:
数字(Number)
字符串(String)
列表(List)
元组(Tuple)
字典(Dictionary)
集合(Set)

4.1 数字(Number)

特点:Number 是不可变的,它不是序列
分类:整数(int),浮点数(float),布尔型(bool)、复数(complex)

  1. 整数(int)
    理论上可以无限大或者无限小,但是受内存的限制,数字越多需要的内存越大,例:999999…,-9999,0,1234
  2. 浮点数(float)
    带一个小数点,也可以加一个科学计数标志e或者E,例:1.23,1.,3.14e-10,4E210,4.0e+210(科学计数法:a×10^b 表示为 aEb 或 aeb)
  3. 布尔型(bool)
    在 Python2 中,没有布尔型,它用数字0表示False,用1表示True;
    在 Python3 中,把Ture和False定义成关键字了,但是他们的值还是1和0,它们可以和数字相加;
  4. 复数(complex)
    实部+虚部,和数学中a+bi是一样的,只不过这里的虚部是以j或者J结尾,例:a = 2 + 1j,b = 1J(注意:j或J前面的系数不能省略)

数字类型转换:

type(object)
返回 object 的类型

print("Hello Python!")
print(123,435,"hello 你好!")

num = int(input())
print(type(num))  # <class 'int'>

name = input("请输入你的姓名:") 
print(name, "您好,很高兴认识你!")
print(type(name))  # <class 'str'>

int([x], base=10)
x:数字或字符串
base:进制数,默认十进制(要用其他进制时,x必须为字符串)
将x转换为整数并返回,如果没有指定x,则返回0

a = int() # 不传入参数时,返回0 
print(a) # 0 

a = int(3.99) # 将浮点型转为整型,直接舍弃小数点后面的数 
print(a) # 3 

a = int("12") # 把整数型字符串"12"转为整型 
print(a) # 12 

# a = int("12.1") # 浮点型的字符串是不行的,会报错 
# print(a)

a = int("101010", base=2) # 基于2进制的"101010"转为十进制的整型 
print(a) # 42 

a = int("0b101010", base=2) # 前面加0b说明是二进制,结果同上
print(a) # 42 

a = int("11", base=8) # 基于8进制的"11"转为十进制的整型 
print(a) # 9 

a = int("0o11", base=8) # 前面加0o说明是八进制,结果同上 
print(a) # 9 

a = int('17', base=16) # 基于16进制的"17"转为十进制的整型 
print(a) # 23 

a = int('0x17', base=16) # 前面加0x说明是十六进制, 结果同上
print(a) # 23

float([x])
x:整数或数字型字符串
将 x 转换成浮点数并返回,不传入参数,则返回 0.0
字符串两头的空格不影响

a = 123 
b = "123" 
c = "1.23" 
print(float()) # 0.0 

a1 = float(a) 
print(a1) # 123.0

b1 = float(b) 
print(b1) # 123.0 

c1 = float(c) 
print(c1) # 1.23

bool([x])
将给定参数转换为布尔类型,True 或 False
如果没有参数(数字0、关键字None、空字符串、空列表、空元组、空字典、空集合),返回 False

# 不管x是什么类型,只要不为空, None 或数字0, 就返回True 
print(bool()) # 没有参数,返回False 
print(bool(0)) # 0判断为False print(bool(None)) # None判断为False 
print(bool([])) # 空的都判断为False 
print(bool(1)) # True 
print(bool(2)) # True 
print(bool("0")) # True

complex([real[, imag]])
创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数
如果没有参数,则返回 0j

# 如果没有参数,则返回 0j 
print(complex()) # 0j 

# 传入两个数字,返回值为 real + imag*1j 的复数 
print(complex(3.2, 1)) # (3.2+1j) 

# 只传入一个数字,imag则默认为0 
print(complex(3.2)) # (3.2+0j) 

# 如果第一个参数是字符串,则它被解释为一个复数,不能传第二个参数,第二个参数不能是字符串 
print(complex("3.2")) # (3.2+0j) 
print(complex("3.2+1j")) # (3.2+1j),注意:"+"号两边不能 有空格,否则报错

4.2 字符串(String)

特点:String 是不可变的,它是序列
单行字符串:用一对单引号或一对双引号定义
多行字符串:用(单引号或双引号组成的)一对三引号来定义(前面提到一对三引号还可以用作多行注释,前面加 # 是单行注释)

s1 = 'hello world' # 一对单引号定义单行字符串 
s2 = "hello world" # 一对双引号定义单行字符串 

# 单引号组成的一对三引号定义多行字符串 
s3 = '''hello world
 hello
       China''' 
print(s3)

# 双引号组成的一对三引号定义多行字符串 
s4 = """hello world hello China"""
""" 这是一个多行的 
注释,它不会被程序运行"""

引号用来定义字符串,那么该如何输出引号?

str(object=‘’)
返回 object 的字符串格式,object默认为空字符串(=‘’),所以不传参时,返回空字符串

4.2.1 转义字符

转义字符:需要在字符串中使用特殊字符时,用反斜杠 \ 转义字符(标亮部分要求掌握,其他作为了解即可)

print("'")  # '
print('"')  # "
print('''"''')  # "
print('''\'''')  # '
print("\'\"")  # '"
print("''")  # ''
print('""')  # ""
print("\\")  # \
print("\\\\")  # \\

str1 = "123456789"
str2 = "123456789"
str3 = "123456"
str4 = "123456"
str5 = "123456"
print(str1, str2, sep = "\t")
print(str1, str2, sep = "   ")
print(str3, str4, sep = "\t")

print(str()) # 返回空字符串 ""
print(str(123456)) # 返回字符串 "123456"

Raw 字符串
很多时候我们并不希望字符串转义,比方说在输入一串网址的时候,里面正好有反斜杠和字母造成了转义,此时为了让该字符串不转义,可以在字符串前面加一个字母 r,表示原始字符串,所有转义都不进行,也就是起到了抑制转义的效果。

print("123\ 456") # 续行符 
print("123\\456") # 反斜杠符号 
print('123\'456') # 单引号 
print("123\"456") # 双引号 
print("123\n456") # 换行 
print("www.baidu.com\n\\") # 原始字符串 
print(r"www.baidu.com\n\\") # 原始字符串 
print(R"www.baidu.com\n\\") # 原始字符串

4.2.2 字符串格式化

  1. % 格式化符号(传统格式化方法)

    %r 保留‘’——repr() 函数将对象转化为供解释器读取的形式
    %b 二进制
    %e 保留小数点后六位,四舍五入
import datetime 
# %f默认精确到小数点后6位 
print("它说它叫%s, 今年%d岁, 每天睡%f小时!" % ("旺财", 2, 8.5)) 
print("它说它叫%s, 擅长%s!" % ("旺财", "汪汪汪")) 
print("它说它叫%r, 擅长%r!" % ("旺财", "汪汪汪")) 
d = datetime.date.today() 
print("%s" % d) 
print("%r" % d) 
print("%c,%c,%c,%c" % (65, 90, 97, 122)) 
print("%c,%c,%c,%c" % ("A", "Z", "a", "z")) 
print("%o" % 20) 
print("%x, %X" % (28, 28))
print("123用科学计数法表示为%e" % 123) 
print("123用科学计数法表示为%E" % 123) 
print("%g" % 1.23456789) # 保留6位有效数字, 考虑四舍五入 
print("%g" % 123456.789) # 保留6位有效数字, 考虑四舍五入 
print("%g" % 1234567.89) # 保留6位有效数字, 整数部分大于6位则用科学计数法表示 
print("%G" % 123456789) # 大写G, 科学计数法时就用大写E表示

在格式化输出数字或字符串时,可以附加辅助指令来完善格式化操作:

PI = 3.141592653 
print("pi1 = %10.3f" % PI) # 最小显示总宽度为10,保留小数点后3位 
print("pi2 = %.*f" % (5, PI)) # 定义精确到小数点后5 
print("pi3 = %*f" % (12, PI)) # 定义最小显示宽度为12,%f默认精确到小数点后6位 
print("pi4 = %010.3f" % PI) # 用0填充空白
print("pi5 = %-10.3f" % PI) # 左对齐,总宽度10个字符,精确到小数点后3位 
print("pi6 = %+f" % PI) # 在正数前面显示正号 print("%o" % 12)
print("%#o" % 12) # 在八进制数前面显示 '0o' 
print("%x" % 24) print("%#x" % 24) # 在十六进制前面显示 '0x' 
print("%X" % 24) print("%#X" % 24) # 在十六进制前面显示 '0X'
  1. format 格式化函数(Python2.6 新增)
# {}是占位符, 当里面为空时, 默认从左往右选择数据 
a = "它说它叫{}, 它今年{}岁, 它宝宝{}个月了!".format("旺 财", 2, 3) 
print(a) 

# 占位符可以填入右边数据的顺序索引来填入对应数据 
b = "它说它叫{1}, 它今年{0}岁, 它宝宝{2}个月了!".format(2, "旺财", 3) 
print(b) 

# 还可以通过关键字来赋值 
c = "它说它叫{name}, 它今年{age01}岁, 它宝宝{age02}个月 了!".format(name="旺财", age01=2, age02=3) 
print(c) 

# format格式化函数的复用性 
d = "它说它叫{name}, 它今年{age}岁, 它宝宝{age}个月 了!".format(name="旺财", age=2) 
print(d)
""" :后面可以附带填充的字符,默认为空格 ^、<、> 分别表示居中、左对齐、右对齐,
后面附带宽度限定值 使用b、d、o、x 分别输出二进制、十进制、八进制、十六进制数
字 使用逗号(,)输出金额的千分位分隔符 """
print('{:>8}'.format('1')) # 总宽度为8,右对齐,默认空格填充
print('{:0>8}'.format('1')) # 总宽度为8,右对齐,使用0填充 
print('{:a<8}'.format('1')) # 总宽度为8,左对齐,使用a填充
print('{:.2f}'.format(3.141592653)) # 浮点数精确到小数点后2位 
print('{:8.2f}'.format(3.141592653)) # 浮点数精确到小数点后2位, 总宽带为8 
print('{:<8.2f}'.format(3.141592653)) # 浮点数精确到小数点后2位, 总宽带为8, 左对齐
print('{:a<8.2f}'.format(3.141592653)) # 浮点数精确到小数点后2位, 总宽带为8, 左对齐, 填充a 

num = 100 
print('{:b}'.format(num)) # 1100100 
print('{:d}'.format(num)) # 100 
print('{:o}'.format(num)) # 144 
print('{:x}'.format(num)) # 64 
print('{:,}'.format(1234567890)) # 1,234,567,890

给定带宽后默认右对齐,未给定带宽则为左对齐;

  1. f-string(Python3.6 新增,推荐)
name = "WangCai" 
age = 2 
# f-string用大括号 {} 表示被替换字段,其中直接填入替换内容: 
print(f"它说它叫{name}, 它{age}岁, 它宝宝{age}月了!") 

# f-string的大括号 {} 可以填入表达式或调用函数,Python会求出其结果并填入返回的字符串内: 
print(f"它说它叫{name}, 它{2+2}岁, 它宝宝{age}月了!") 
print(f"它说它叫{name.upper()}, 它{4//2}岁, 它宝宝{age}月了!")
""" :后面可以附带填充的字符,默认为空格 ^、<、> 分别表示居中、左对齐、右对齐,
后面附带宽度限定值 使用b、d、o、x 分别输出二进制、十进制、八进制、十六进制数
字 使用逗号(,)输出金额的千分位分隔符 """
num = 1 
print(f'{num:>8}') # 总宽度为8,右对齐,默认空格填充 
print(f'{num:0>8}') # 总宽度为8,右对齐,使用0填充 
print(f'{num:a<8}') # 总宽度为8,左对齐,使用a填充 

PI = 3.141592653 print(f'{PI:.2f}') # 浮点数精确到小数点后2位
print(f'{PI:8.2f}') # 浮点数精确到小数点后2位, 总宽带为8 
print(f'{PI:<8.2f}') # 浮点数精确到小数点后2位, 总宽带为8, 左对齐 
print(f'{PI:a<8.2f}') # 浮点数精确到小数点后2位, 总宽带为8, 左对齐, 填充a 

num = 100 
print(f'{num:b}') # 1100100 
print(f'{num:d}') # 100 
print(f'{num:o}') # 144 
print(f'{num:x}') # 64 
print(f'{1234567890:,}') # 1,234,567,890

//——整除
.upper——字符串大写

4.2.3 字符串对象方法

str.replace(old, new[, count])
old:旧字符串——必须参数
new:新字符串——必须参数
count:要替换的最大次数,默认为-1,替换所有能替换的——可选参数用新字符串替换旧字符串并返回

s = "Line1 Line2 Line4" 
# 用 "b" 替换所有的 "Li" 
rs = s.replace("Li", "b") 
print(rs) # bne1 bne2 bne4 

# 用 "b" 替换 "Li" 2次 
rs = s.replace("Li", "b", 2) 
print(rs) # bne1 bne2 Line4

str.strip([chars])
chars:指定要移除的字符序列,如果没有指定,则默认移除字符串两边空白符(空格、换行符、制表符)
从字符串左右两边删除字符序列(会考虑chars的所有组合)——遇到不符合的则停止;

str.lstrip([chars]) 、str.rstrip([chars]) 也是同理,只不过一个是从左边删除,一个从右边删除而已

str1 = ' \thello wrold h \n' 
# 没有传参,删除字符串两边的空白符(空格、换行符、制表符) 
print(str1.strip()) # hello wrold h 

str2 = "ooho hello wrold" 
# 移除str2头尾的字符"o",头部有两个连续的,都移除,尾部没有可以移除的 
print(str2.strip('o')) # ho hello wrold 

# 会考虑"mecow."的所有组合情况来移除头尾的字符 
str3 = 'www.example.com' 
print(str3.strip("mecow.")) # xampl

str.center(width[, fillchar])
width:指定字符串长度
fillchar:填充的字符,必须是单个字符,默认为空格符
返回长度为 width 的字符串,原字符串在其正中,使用指定的fillchar 填充两边的空位;如果 width 小于等于 len(s) 则返回原字符串
当左右填充不平衡时,原字符串长度为奇数时,左边填充更少,原字符串长度为偶数时,左边填充更多

str1 = "hello " 
print(str1.center(11, "F"))  # FFFhello FF 
print(str1.center(10, "F"))  # FFFhello FF 
print(str1.center(12, "F"))  # FFFhello FF 
print(str1.center(3, "F"))  # hello

str.ljust(width[, fillchar])
width:指定字符串长度
fillchar:填充的字符,必须是单个字符,默认为空格符
返回长度为 width 的字符串,原字符串在其中靠左对齐,使用指定的 fillchar 填充空位;如果 width 小于等于 len(s) 则返回原字符串

str.rjust(width[, fillchar]) 也是同理,只不过原字符串在其中靠右对齐

str1 = "hello " 
print(str1.ljust(11, "F"))  # hello FFFFF 
print(str1.ljust(3, "F"))  # hello 
print(str1.rjust(11, "F"))  # FFFFFhello 
print(str1.rjust(3, "F"))  # hello

str.partition(sep)
sep:分隔符,可以是字符或者字符串
在 sep 首次出现的位置拆分字符串,返回一个包含三个元素的元组,元素分别是分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,则返回的元组包含原字符串本身以及两个空字符串。

str.rpartition(sep) 也是同理,只不过是从最后一次出现的位置拆分;未找到分隔符返回的元组包含两个空字符串以及原字符串本身。其他一样。

str2 = "hello world" 
print(str2.partition("l"))  # ('he', 'l', 'lo world')
print(str2.partition("ll"))  # ('he', 'll', 'o world')
print(str2.partition("hd"))  # ('hello world', '', '')
print(str2.rpartition("l"))  # ('hello wor', 'l', 'd')
print(str2.rpartition("ll"))  # ('he', 'll', 'o world')
print(str2.rpartition("hd"))  # ('', '', 'hello world')

str.startswith(prefix[, start[, end]])
prefix:匹配的前缀,可以是字符,字符串或者它们组成的元组(元组中只要一个元素满足即可)
start:开始索引
end:结束索引(不包括该索引)
如果字符串以指定的 prefix 开始,返回 True,否则返回 False;如果有可选项 start,将从所指定位置开始检查; 如果有可选项end,将在所指定位置停止比较

str1 = "hello world" 
print(str1.startswith("h")) # True 
print(str1.startswith("he")) # True 
print(str1.startswith(" w")) # False 
print(str1.startswith(" w", 5, 8)) # True 
print(str1.startswith((" w", "h"))) # True

str.endswith(suffix[, start[, end]])
suffix:匹配的后缀,可以是字符,字符串或者它们组成的元组(元组中只要一个元素满足即可)
start:开始索引
end:结束索引(不包括该索引)如果字符串以指定的 suffix 结束,返回 True,否则返回 False;如果有可选项 start,将从所指定位置开始检查; 如果有可选项end,将在所指定位置停止比较

str1 = "hello world" 
print(str1.endswith("d")) # True 
print(str1.endswith("ld")) # True 
print(str1.endswith("lo")) # False 
print(str1.endswith("lo", 1, 5)) # True 
print(str1.endswith(("d", "lo"))) # True

str.isalnum() 如果字符串中的所有字符都是字母、文字或数字,则返回True,否则为 False

str.isalpha() 如果字符串中的所有字符都是字母,则返回 True,否则为False

str.isdigit() 如果字符串中的所有字符都是数字,则返回 True,否则为False

str.isspace() 如果字符串中只有空白字符(空格、换行符、制表符),则返回 True,否则为 False

str1 = "abc牛123" 
print(str1.isalnum()) # True 
print(str1.isalpha()) # False 
str2 = "abc" print(str2.isalpha()) # True 
print(str1.isdigit()) # False 
print(str2.isdigit()) # False 
str3 = "123" 
print(str3.isdigit()) # True 
print(str1.isspace()) # False 
str4 = " " 
print(str4.isspace()) # True 
str5 = "\t" 
print(str5.isspace()) # True 
str6 = "\n" print(str6.isspace()) # True

str.join(iterable)
iterable:包括 string、list、tuple、dict、set等等
将可迭代对象中的元素(元素必须是字符串类型)以指定的字符连接并返回(返回的字符串类型)

a = "\\" # 单个反斜杠 
s1 = "hello world" 
print(a.join(s1))  # h\e\l\l\o\ \w\o\r\l\d
print(a.join(['123','45']))  # 123\45
s2 = ["1", "2", "3", "4"]  
print(a.join(s2))  # 1\2\3\4  
s3 = ("1", "2", "3", "4")
print(a.join(s3))   # 1\2\3\4  

# 字典只取键, 不取值 
s4 = {"身高":175, "体重":65} 
print(a.join(s4))  # 身高\体重 

# 集合无序,所以这里结果不是确定的 
s5 = {"1", "2", "3", "1"} # 去重 
print(a.join(s5))  # 2\3\1 (顺序不重复)

str.count(sub, start, end)
sub:指定的子字符串
start:字符串开始搜索的位置索引,默认为0
end:字符串中结束搜索的位置索引(不包括这个位置),默认为len(str)
返回子字符串在字符串中出现的次数(默认全局搜索)

a = "hello world" 
a1 = a.count("l") # 3 
a2 = a.count("l", 0, 3) # 1 
a3 = a.count("hel", 0, 3) # 1 
a4 = a.count("hle", 0, 3) # 0 
print(a1) # 3 
print(a2) # 1 
print(a3) # 1 
print(a4) # 0

str.capitalize() 将字符串的首字母变成大写,其他字母变小写,并返回

str.title() 将字符串中所有单词的首字母变成大写,其他字母变小写,并返回

str.upper() 将字符串中所有字符变成大写,并返回

str.lower() 将字符串中所有字符变成小写,并返回

str.swapcase() 将字符串中所有大写字符变成小写,小写变成大写,并返回

a = "hello world" 
b = a.capitalize() 
print(b) # Hello world 
c = a.title() 
print(c) # Hello World 
d = a.upper() 
print(d) # HELLO WORLD 
e = d.lower() 
print(e) # hello world 
f = c.swapcase() 
print(f) # hELLO wORLD

str.find(sub[, start[, end]]) 返回从左开始第一次找到指定子字符串时的索引,找不到就返回 -1

str.rfind(sub[, start[, end]]) 返回从右开始第一次找到指定子字符串时的索引,找不到就返回 -1

str.index(sub[, start[, end]]) 类似于find(),唯一不同在于,找不到就会报错,其他都一样
sub:指定的子字符串
start:字符串开始搜索的位置索引,默认为0
end:字符串中结束搜索的位置索引(不包括这个),默认为len(str)
注意:返回索引时,是返回原字符串中的索引值

str.rindex(sub[, start[, end]]) 类似于rfind(),唯一不同在于,找不到就会报错,其他都一样

s = "hello world" 
a = s.find("l") # 2 
b = s.rfind("l") # 9 
print(a, b) 
print(s.rfind("lo")) # 3
print(s.find("lo"))  # 3
print(s.find("ol"))  # -1

a = s.find("l", 4) # 9 
b = s.rfind("l", 4) # 9 
print(a, b) 

a = s.find("ell", 1, 5) # 1 
b = s.rfind("ell", 1, 5) # 1 
print(a, b)

print(s.index("ol"))  # baocuo

str.split(sep=None, maxsplit=-1)——与str.partition(sep)区分
sep:用于分割字符串的分隔符, 默认为所有的空白符(空格、换行、制表符等)
maxsplit:最大分隔次数,默认为-1,即分隔所有
通过指定分隔符对字符串进行分割, 以字符串列表的形式返回(分割结果不包括分隔符)

str.rsplit(sep=None, maxsplit=-1) 也是同理,只不过是maxsplit从右边开始

s = " Line1-abcdef  \nLine2-abc \nLine4-abcd" 
print(s) 
''' Line1-abcdef 
Line2-abc
Line4-abcd'''
# 默认按照所有的空白符(空格、换行、制表符等)来分割, 并从结果中丢弃空字符串 
a = s.split() 
print(a)  # ['Line1-abcdef', 'Line2-abc', 'Line4-abcd']

# 按照指定的一个空格" "来分割 
a = s.split(" ") 
print(a)  # ['', 'Line1-abcdef', '', '\nLine2-abc', '\nLine4-abcd']
print(s.split("  "))  # [' Line1-abcdef', '\nLine2-abc \nLine4-abcd']
print(s.split("\n"))  # [' Line1-abcdef  ', 'Line2-abc ', 'Line4-abcd']
print(s.split("\\"))  # [' Line1-abcdef  \nLine2-abc \nLine4-abcd']  (\\代表\,\n是一个字符,无法拆分)
s2 = r" Line1-abcdef  \nLine2-abc \nLine4-abcd" 
print(s2.split("\\"))  # [' Line1-abcdef  ', 'nLine2-abc ', 'nLine4-abcd']

# 按照指定的"Li"来分割2次 
a = s.split("Li", 2) 
print(a)  # [' ', 'ne1-abcdef  \n', 'ne2-abc \nLine4-abcd']

# maxsplit按照指定的"Li"从右边开始 
a = s.rsplit("Li", 2) 
print(a)  #  [' Line1-abcdef  \n', 'ne2-abc \n', 'ne4-abcd']

4.3 列表(List)

List 是可变的,它是序列;
在方括号中添加元素,并使用逗号隔开;

list0 = [] 
list1 = ['China', 1997, 2000] 
list2 = [1, 2, 3, 4, 5] 
list3 = ["a", "b", "c", "d"]
list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black']

列表可以嵌套:

lis = [1, 2, [3, 4, [5, 6]]]
print(type(lis))  # <class 'list'>
print(len(lis))  # 3
print(lis[2])  # [3, 4, [5, 6]]
print(lis[2][2])  # [5, 6]
print(lis[2][-1])  # [5, 6]

print(lis[-1][-1][0])
lis[-1][-1][0] = [8]
print(lis)
lis[-1][-1][0] = 8
print(lis)

print(lis[-1][-1][:1])
# lis[-1][-1][:1] = 10  #baocuo
print(lis)
lis[-1][-1][:1] = [10]  # [1, 2, [3, 4, [10, 6]]]
print(lis)
lis[-1][-1][:1] = [[10]]  # [1, 2, [3, 4, [[10], 6]]]
print(lis)

4.3.1 修改列表

列表是可变的,所以我们可以通过索引和切片的方式来对列表的元素进行修改

list1 = ["H", "e", "l", "l", "o", " ", "1", "牛", "3"] 
# 通过索引把列表下标为4对应的元素改为 "-" 
list1[4] = "-" 
print(list1) 

# 通过切片把列表的前 4 个元素变成大写的字母 
list1[0: 4] = ["h", "E", "L", "L"] 
print(list1)

list([iterable])
将一个iterable(可迭代)对象转化为列表并返回,如果没有传入参数返回空的列表

print(list()) # []
print(list("China")) # ['C', 'h', 'i', 'n', 'a'] 
print(list((1, 2, 3))) # [1, 2, 3] 
print(list({1:2, 3:4})) # [1, 3] 
print(list({1, 2, 3, 4})) # [1, 2, 3, 4]

4.3.2 列表对象方法

list.append(x)
在列表的末尾添加一个元素(修改原列表,无返回值),相当于a[len(a):] = [x]

li = [1, 2] 
li.append(1) # 添加数字 
print(li) 
li.append("1") # 添加字符串 
print(li) 
li.append([1, 2]) # 添加列表 
print(li)
li.append((3, 4)) # 添加元组 
print(li) 
li.append({"身高": 175}) # 添加字典 
print(li) 
li.append({5, 6}) # 添加集合 
print(li)

lis1 = [1, 2]
lis2 = lis1
print(lis1.append(3))  # None  ——无返回值
print(lis2)  # [1, 2, 3]

lis1.append(3)
print(lis1)  # [1, 2, 3, 3]
print(lis2)  # [1, 2, 3, 3]

str1 = '123'
str2 = str1
print(str2)  # 123
print(str1.replace('1', '4'))  # 423
print(str2)  # 123
str1.replace('2', '5')
print(str2)  # 123

lis3 = [1, 2, 3]
lis3[len(lis3):] = [5]
# lis3[len(lis3)] = [5]  # baocuo
print(lis3)  # [1, 2, 3, 5]
print(lis3[len(lis3):])  # []

list.extend(iterable)
使用iterable中的所有元素来扩展列表(修改原列表,无返回值),相当于 a[len(a):] = iterable

li = [1, 2] 
li.extend("123") # 添加字符串中的元素 
print(li)  # [1, 2, '1', '2', '3']
li.append('123')
print(li)  # [1, 2, '1', '2', '3', '123']

li.extend([1, 2]) # 添加列表中的元素 
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2]  

li.extend((3, 4)) # 添加元组中的元素 
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4]

li.extend({"身高": 175}) # 添加字典中的 键 
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4, '身高']

li.extend({5, 6}) # 添加集合中的元素 
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4, '身高', 5, 6]

li.append([1,2])  
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4, '身高', 5, 6, [1, 2]]

li[len(li):] = 4, 5, "n"  # {} () []
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4, '身高', 5, 6, [1, 2], 4, 5, 'n']

li[len(li):] = [(4, 5, "n")]
print(li)  # [1, 2, '1', '2', '3', '123', 1, 2, 3, 4, '身高', 5, 6, [1, 2], 4, 5, 'n', (4, 5, 'n')]

list.insert(i, x)
i:要插入的元素的索引
x:要插入的元素
在给定的位置插入一个元素(修改原列表,无返回值)

在这里插入代码片li = [1, 2, 3, 4, True, False] 
a = [5, 6, 7] 
li.insert(1, a)  # [1, [5, 6, 7], 2, 3, 4, True, False]
print(li)

li.insert(1, [])
print(li)  # [1, [], [5, 6, 7], 2, 3, 4, True, False

list.sort( [key], reverse=False)
key:指定一个函数(函数名), 在排序之前, 列表每个元素都先应用这个函数之后再排序
reverse:默认为 False,代表升序,指定为 True 则降序(区分大小写)
对原列表进行排序,无返回值

num_list = [1, -2, 5, -3]
# 默认reverse=False升序 
num_list.sort() 
print(num_list) # [-3, -2, 1, 5] 

# 指定reverse=True降序 
num_list.sort(reverse=True) 
print(num_list) # [5, 1, -2, -3] 

# key指定为内置函数abs(x), 列表中的每个元素在排序之前, 先应用这个函数,
# 然后根据应用之后的大小来对原数据排序 
num_list.sort(key=abs) # [1, -2, 5, -3] abs-> [1, 2, 5, 3] -> [1, 2, 3, 5] 
print(num_list) # [1, -2, -3, 5]

li2 = [1, -3, -5] 
def func(x):
    return x**2

li2.sort(key = func, reverse = True)
print(li2)

sorted(iterable, [key], reverse=False)
iterable:可迭代对象(字符串,列表,元组,字典,集合等)
key:指定一个函数, 在排序之前, 每个元素都先应用这个函数之后再排序
reverse:默认为 False,代表升序,指定为 True 则降序(区分大小写)
对可迭代对象进行排序(不对原数据进行操作),以列表形式返回

num_tup = (1, -2, 5, -3) 
result = sorted(num_tup, reverse=False) 
print(result) # [-3, -2, 1, 5] 

result = sorted(num_tup, reverse=True) 
print(result) # [5, 1, -2, -3] 

result = sorted(num_tup, key=abs) 
print(result)# [1, -2, -3, 5]

sort 和 sorted 的区别:
list.sort 是只针对列表的排序,对原数据进行操作,无返回值,是列表的对象方法
sorted 可以对所有可迭代的对象进行排序,不对原数据操作,有返回值,是内置函数

li2 = [1, -3, -5]
print(sorted(li2))  # [-5, -3, 1]

li3 = ['123', '456','1', '11']
print(sorted(li3))  # ['1', '11', '123', '456']

str1 = 'a5b42/n'
print(sorted(str1))  # ['/', '2', '4', '5', 'a', 'b', 'n']

list.reverse()
对列表中的元素反向,无返回值

li = [1, 3, 5, 2] 
li.reverse() 
print(li) # [2, 5, 3, 1]

reversed(seq)
对给定序列返回一个反向迭代器

reverse 和 reversed 区别:
list.reverse是只针对列表的,对原数据进行操作,无返回值,是列表的对象方法
reversed 是针对序列的,不对原数据操作,返回一个反向迭代器,是内置函数

seqString = 'hello world' 
result = reversed(seqString) 
print(result) # 一个反向迭代器 
print(list(result)) # list转化成列表

list.count(x)
返回元素 x 在列表中出现的次数

a = [1, 23, 1, 3, 23, "23"] 
print(a.count(23)) # 2

list.index(x[, start[, end]])
x:要找的值
start:查找的起始索引位置,默认为 0
end:查找的结束索引位置(不包括这个索引),默认为 len(list)
返回从列表中第一次找到指定值 x 的位置索引,找不到则抛出ValueError 异常

注意:返回的索引是相对于整个序列开始计算的,而不是[start:stop] 的子序列

a = [1, 2, 3, 4, 3, 2, 3] 
# 找到第一个3的位置索引是2 
print(a.index(3)) # 2 
# 在索引[3,5)位置区间, 找到第一个3的位置索引是4 
print(a.index(3, 3, 5)) # 4

list.pop([i])
i:要删除元素的索引
删除列表中给定位置的元素(修改原列表)并返回该元素
如果没有给定位置,将会删除并返回列表中的最后一个元素

li = [1, 2.3, 2+3j, "4", True, False] 
print(li.pop()) # 未给定参数,则删除最后一个元素并返回 
print(li) # 删除元素后的列表 
print(li.pop(2)) # 删除索引2对应的元素 
print(li) # 删除元素后的列表

list.remove(x)
移除列表中第一个匹配到的值为 x 的元素(修改原列表,无返回值)
如果没有这样的元素,则抛出 ValueError 异常
自动向前补充——循环时会遇到问题

li = [1, 2, 4, 2, 3, 3] 
li.remove(2) # 移除第一个2 
li.remove(3) # 移除第一个3 
print(li) # [1, 4, 2, 3] 
li.remove(5) # 没有5,则抛出 ValueError 异常

list.copy()
返回列表的一个浅拷贝,等价于 a[:]
规避可变对象(列表、字典、集合)的风险

li1 = [1, 2, 4, 2, 3, 3] 
li2 = li1.copy() 
print(li2) # [1, 2, 4, 2, 3, 3]

list.clear()
移除列表中的所有元素(修改原列表,无返回值),等价于 del a[:]
——可变对象(列表、字典、集合)

li = [1, 2, 4, 2, 3, 3] 
li.clear() 
print(li) # []

4.4 元组(Tuple)

Tuple 与 List 类似,它也是序列,但 Tuple 是不可变的
在圆括号中添加元素,并使用逗号隔开(或者不加括号也认为是元组)

# 空元组 
tup = ()
print(type(tup)) 

# 空列表 
lis = [] 
print(type(lis))
# 元组 
tup = (1, ) 
print(tup) 
print(type(tup)) 

# 数字 
num = (1) 
print(num) 
print(type(num)) 

# 列表 
lis = [1, ] 
print(lis) 
print(type(lis)) 

# 列表
lis = [1] 
print(lis) 
print(type(lis))
tup1 = ('China', 1997, 2000) 
tup2 = (1, 2, 3, 4, 5) 
tup3 = "a", "b", "c", "d" # 不需要括号也可以
# Tuple 是不可变的,但是 Tuple 中的列表是可变的 
tup = (1, 2, [3, 4, 5]) 
lis = tup[2] 
lis[2] = 6 
print(lis)  # [3, 4, 6]
tup[2][2] = 7 
# tup[1] = 0  baocuo
print(lis)  # [3, 4, 7]
print(tup)  # (1, 2, [3, 4, 7])

tuple([iterable])
返回一个新的 tuple 对象,其元素来自于 iterable,如果未指定iterable,则将返回空元组

print(tuple()) # 返回空元组 () 
print(tuple("China")) # ('C', 'h', 'i', 'n', 'a') 
print(tuple([1, 2, 3])) # (1, 2, 3)
print(tuple({1:2, 3:4})) # (1, 3) 
print(tuple({1, 2, 3, 4})) # (1, 2, 3, 4)

元组对象方法

tuple.count(x)
返回元素 x 在元组中出现的次数

a = (1, 23, 1, 3, 23, "23")
print(a.count(23)) # 2

tuple.index(x[, start[, stop]])
x:要找的值
start:查找的起始索引位置,默认为 0
stop:查找的结束索引位置(不包括这个索引),默认为 len(list)
返回从元组中第一次找到指定值 x 的位置索引,找不到则抛出ValueError 异常
注意:返回的索引是相对于整个序列开始计算的,而不是[start:stop] 的子序列

a = (1, 2, 3, 4, 3, 2, 3) 

# 找到第一个3的位置索引是2 
print(a.index(3)) # 2 
# 在索引[3,5)位置区间, 找到第一个3的位置索引是4 
print(a.index(3, 3, 5)) # 4

4.5 字典(Dictionary)

字典的每个键值对 key: value 用冒号 : 分割,每个对之间用逗号(,)分隔,包括在花括号 {} 中
Dict 是可变的,它不是序列(3.6版本之后有序)
键和键包含的内容都必须为不可变类型(如数字,字符串或元组)
如果键重复,那么重复键对应的值后面会把前面的值覆盖掉,但是位置还是原来的位置
值的数据类型没有严格的限制,并且可以重复

4.5.1 创建字典的六种方式

  1. 直接在空字典 {} 里面写键值对
a = {'姓名': '张三', '年龄': 28} 
print(a)
  1. 定义一个空字典,再往里面添加键值对
a = dict() # a = {} 这样写也可以 
a['姓名'] = '张三' 
a['年龄'] = 28 print(a)
  1. 把键作为关键字传入
a = dict(姓名 = "张三", 年龄 = 28) 
print(a) # {"姓名": "张三", "年龄": 28}
  1. 可迭代对象方式来构造字典
a = dict([("姓名", "张三"), ("年龄", 28)]) # 这里用元组/ 列表/集合都是可以的 
print(a)

dict(**kwarg) / dict(mapping) / dict(iterable)
用于创建一个字典并返回(**不定长参数)

print(dict(one=1, two=2, three=3)) # 传入关键字来构造字典
print(dict(zip(["one", "two", "three"], [1, 2, 3]))) # 映射函数方式来构造字典 
print(dict([("one", 1), ("two", 2), ("three", 3)])) # 可迭代对象方式来构造字典
  1. 通过 zip() 把对应元素打包成元组,类似于上一种方法
print(dict(zip(["one", "two", "three"], [1, 2, 3]))) #映射函数方式来构造字典 
result = zip(['one', 'two', 'three'], [1, 2, 3])
print(list(result))  # [('one', 1), ('two', 2), ('three', 3)]
dic = dict(result)
print(dic)  # {}
result = zip(['one', 'two', 'three'], [1, 2, 3])
dic = dict(result)
print(dic)  # {'one': 1, 'two': 2, 'three': 3}

zip(*iterables)
返回一个元组的迭代器,其中的第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素
当所输入可迭代对象中最短的一个被耗尽时,迭代器将停止迭代
不带参数时,它将返回一个空迭代器
当只有一个可迭代对象参数时,它将返回一个单元组的迭代器

result1 = zip("abcd", "efgh") 
print(list(result1))  # [('a', 'e'), ('b', 'f'), ('c', 'g'), ('d', 'h')]
result2 = zip("abcd", "efg") 
print(list(result2))  # [('a', 'e'), ('b', 'f'), ('c', 'g')]
result3 = zip() 
print(list(result3))  # []
print(result3)  # <zip object at 0x000002773D99D2C0>
result4 = zip("abcd") 
print(list(result4))  # [('a',), ('b',), ('c',), ('d',)]
  1. 利用类(class)方法 fromkeys() 创建
# 类方法的值无法定制化
dic1 = dict.fromkeys(("name", "age", "sex")) 
print(dic1)  # {'name': None, 'age': None, 'sex': None}
dic2 = dict.fromkeys(("name", "age", "sex"), "I don't know!") 
print(dic2)  # {'name': "I don't know!", 'age': "I don't know!", 'sex': "I don't know!"}
dic3 = dict.fromkeys(("name", "age", "sex"), (1, 2, 3)) 
print(dic3)  # {'name': (1, 2, 3), 'age': (1, 2, 3), 'sex': (1, 2, 3)}

# 实例对象调用
a = {}
dic = a.fromkeys(("name", "age", "sex"), (1, 2, 3)) 
print(dic3)  # {'name': (1, 2, 3), 'age': (1, 2, 3), 'sex': (1, 2, 3)}

classmethod fromkeys(iterable[, value])
创建一个新字典,以 iterable 的元素作为键,value 作为值,value默认为 None

dic1 = dict.fromkeys(("name", "age", "sex")) 
print(dic1) 
dic2 = dict.fromkeys(("name", "age", "sex"), "I don't know!") 
print(dic2)

4.5.2 访问和修改字典

访问字典里的值:

diction = {'Name': '小明', 'Age': 7, 'Class': 'First'} 
print(diction['Name']) # '小明' 
print(diction['Age']) # 7 
# print(diction['age']) # 没有找到键, 则报错 KeyError

修改字典(可以嵌套):

# 指定键值对, 如果键已经存在, 则修改值;如果键不存在, 则在最后增 加键值对 
d1 = {"身高":175, "体重":65} 
d1["身高"] = "1米75" 
d1["名字"] = {"张三" : 123 , "lisi" : 456}
print(d1) # {'身高': '1米75', '体重': 65, '名字': '张 三'}

print(d1['名字'])  # {'张三': 123, 'lisi': 456}
print(d1["名字"]['lisi'])  # 456

4.5.3 字典的对象方法

dict.keys()
返回由字典键组成的一个新视图
返回的对象是视图对象,这意味着当字典改变时,视图也会相应改变

d1 = {'身高':175, '体重':65, '肤色':'黑色', '名字':'张三'} 
a = d1.keys() 
print(a) # dict_keys(['身高', '体重', '肤色', '名字']) 
print(list(a)) # ['身高', '体重', '肤色', '名字'] 
b = list(a)
print(b) # ['身高', '体重', '肤色', '名字'] 

d1["性别"] = "女" 
print(a) # dict_keys(['身高', '体重', '肤色', '名字', '性别']) 
print(list(a)) # ['身高', '体重', '肤色', '名字', '性别'] 
print(b) # ['身高', '体重', '肤色', '名字']

dict.values()
返回由字典值组成的一个新视图
返回的对象是视图对象,这意味着当字典改变时,视图也会相应改变

d1 = {'身高':175, '体重':65, '肤色':'黑色', '名字':'张三'} 
a = d1.values() 
print(a) # dict_values([175, 65, '黑色', '张三']) 
print(list(a)) # [175, 65, '黑色', '张三'] 
b = list(a) 
print(b) # [175, 65, '黑色', '张三'] 

d1["肤色"] = "黄色" 
print(a) # dict_values([175, 65, '黄色', '张三']) 
print(list(a)) # [175, 65, '黄色', '张三'] 
print(b) # [175, 65, '黑色', '张三']

dict.items()
返回由字典项 ((键, 值) 对) 组成的一个新视图
返回的对象是视图对象,这意味着当字典改变时,视图也会相应改变

d1 = {'身高':175, '体重':65, '肤色':'黑色', '名字':'张三'} 
a = d1.items() 
print(a) # dict_items([('身高', 175), ('体重', 65), ('肤色', '黑色'), ('名字', '张三')])
print(list(a)) # [('身高', 175), ('体重', 65), ('肤色', '黑色'), ('名字', '张三')] 
b = list(a) 
print(b) # [('身高', 175), ('体重', 65), ('肤色', '黑 色'), ('名字', '张三')] 
d1["体重"] = 77 
d1["性别"] = "女" 
print(a) # dict_items([('身高', 175), ('体重', 77), ('肤色', '黑色'), ('名字', '张三'), ('性别', '女')]) 
print(list(a)) # [('身高', 175), ('体重', 77), ('肤色', '黑色'), ('名字', '张三'), ('性别', '女')] 
print(b) # [('身高', 175), ('体重', 65), ('肤色', '黑 色'), ('名字', '张三')]

dict.get(key[, default])
key:指定的键
default:如果指定的键不存在时,返回该值,默认为 None
返回指定的键 key 对应的值, 如果 key 不在字典中,则返回 default

dic = {"身高":175, "体重":65} 
value = dic.get("体重") 
print(value) # 65 value = dic["体重"] 
print(value) # 65 value = dic.get("体", "KeyError") 
print(value) # 返回一个字符串:"KeyError" value = dic["体"] 
print(value) # 报错:KeyError

dict.update([other])
使用来自 other 的键 / 值对更新字典,如果键相同,则覆盖原有的键

d1 = {'身高':175, '名字':'张三'} 
d2 = {'肤色': '巨黑'} 
d3 = {'身高': '1米75'} 

# other 为另一个字典对象
d1.update(d2) 
print(d1)  # {'身高': 175, '名字': '张三', '肤色': '巨黑'}
d1.update(d3) 
print(d1)  # {'身高': '1米75', '名字': '张三', '肤色': '巨黑'}

# other 为一个包含键/值对的可迭代对象 
d1.update([("地址", "不详"), ("性别", "男")]) 
print(d1)  # {'身高': '1米75', '名字': '张三', '肤色': '巨黑', '地址': '不详', '性别': '男'}
d1.update(dict([("地址2", "不详"), ("性别2", "男")])) 
print(d1)  # {'身高': '1米75', '名字': '张三', '肤色': '巨黑', '地址': '不详', '性别': '男', '地址2': '不详', '性别2': '男'}

# other 为关键字参数 
d1.update(体重 = 105, 肤色 = '小白')
print(d1)  # {'身高': '1米75', '名字': '张三', '肤色': '小白', '地址': '不详', '性别': '男', '地址2': '不详', '性别2': '男', '体重': 105}

dict.pop(key[, default])
key:指定的键
default:指定当键不存在时应该返回的值
移除指定的键 key , 并返回对应的值, 如果 key 不在字典中,则返回 default
如果 default 未给出且 key 不存在于字典中,则会引发 KeyError

d1 = {'身高':175, '名字':'张三', '年龄':18} 
value1 = d1.pop('年龄')  
print(d1)  # {'身高': 175, '名字': '张三'}
print(value1)  # 18

# value2 = d1.pop('年') baocuo

value2 = d1.pop('名字','nv')
print(d1)  # {'身高': 175}
print(value2)  # 张三

dict.popitem()
从字典中移除最后一个键值对, 并返回它们构成的元组 (键, 值)

dic = {'name': '小明', '年龄': 18, '学历': '本科'}
item = dic.popitem()
print(item)  # ('学历', '本科') 
print(dic)  # {'name': '小明', '年龄': 18}

item = dic.popitem() 
print(item)  # ('年龄', 18)
print(dic)  # {'name': '小明'}

dict.setdefault(key[, default])
如果字典存在键 key,返回它的值
如果不存在,插入值为 default 的键 key,并返回 default,default默认为 None

dic = {'name': '小明', '年龄': 18, '学历': '本科'} 
item = dic.setdefault('年龄') 
print(item)  # 18

item = dic.setdefault("性别") 
print(item)  # None
print(dic)  # {'name': '小明', '年龄': 18, '学历': '本科', '性别': None}
item = dic.setdefault("地址", "不详") 
print(item)  # 不详
print(dic)  # {'name': '小明', '年龄': 18, '学历': '本科', '性别': None, '地址': '不详'}

dict.copy()
返回原字典的浅拷贝——(列表、字典、集合)

dic = {'name': '小明', '年龄': 18, '学历': '本科'} 
new_dic = dic.copy() 
print(new_dic) # {'name': '小明', '年龄': 18, '学历': '本科'}

dict.clear()
移除字典中的所有元素,无返回值

dic = {'name': '小明', '年龄': 18, '学历': '本科'} 
dic.clear() 
print(dic) # {}

dict.has_key(key)
如果键在字典dict里返回true,否则返回false

key in dict
如果键在字典dict里返回true,否则返回false

popitem()返回并删除字典中的最后一对键和值。

4.7 集合(Set)

Set 可以改变,它不是序列
无序性(集合元素是没有顺序的)
不重复性(元素是不重复的,即使有多个相同元素也会去重)

集合里只能包含不可变的数据类型
可以使用花括号 { } 或者 set() 函数创建集合
创建空集合必须用 set(),因为 { } 是用来创建空字典的

set01 = {1, 2, "4", (5, 6)} 
print(set01) 
set02 = set() # 定义空集合 
print(set02) dict01 = {} # 定义空字典 
print(type(dict01)) # <class 'dict'>

set([iterable])
返回一个新的 set 对象,其元素来自于 iterable,如果未指定iterable,则将返回空集合

print(set()) # set() 空集合
print(set("China")) # {'a', 'C', 'i', 'h', 'n'} 
print(set([1, 2, 3])) # {1, 2, 3} 
print(set((1, 2, 3))) # {1, 2, 3} 
print(set({1:2, 3:4})) # {1, 3}

frozenset([iterable])
返回一个新的 frozenset 对象,即不可变的集合,其元素来自于iterable,如果未指定参数,则返回冻结的空集合
作用:set 中的元素必须是不可变类型的,而 frozenset 是可以作为 set 元素的

print(frozenset()) # frozenset() 
print(frozenset("1234")) # frozenset({'4', '3', '1', '2'}) 
print(frozenset([1, 2, 3, 4])) # frozenset({1, 2, 3, 4}) 
print(frozenset({"one":1, "two":2, "three":3})) # frozenset({'two', 'three', 'one'}) 
set1 = {"four"} 
set1.add(frozenset({'two', 'three', 'one'})) 
print(set1) # {frozenset({'one', 'two', 'three'}), 'four'}

利用集合特性,可以用来 去重关系测试

# 把一个列表变成集合,就会自动去掉重复的元素 
li = [1, 2, 4, 5, 7, 7, 4, 5] 
a = set(li) 
print(a) 

# 测试两组数据之间的交集、差集、并集等关系 
a = set("abdefga") 
b = set("abc") 
c = set("aef") 
print(c <= a) # 判断c是否是a的子集 
print(a - b) # 返回a和b的差集 
print(a | b) # 返回a和b的并集 
print(a & b) # 返回a和b的交集 
print(a ^ b) # 返回a和b中不同时存在的元素(对称差)

集合的对象方法

  1. set 和 frozenset 对象都可用:

isdisjoint(other)
other:Iterable
如果集合中没有与 other 共有的元素则返回 True

str1 = "145" 
list1 = [1, 4] 
dic1 = {1:"1"} 

set1 = {"1", 2, 3} 
print(set1.isdisjoint(str1)) # False 
print(set1.isdisjoint(list1)) # True 
print(set1.isdisjoint(dic1)) # True 

fset = frozenset(["1", 2, 3]) 
print(fset.isdisjoint(str1)) 
print(fset.isdisjoint(list1)) 
print(fset.isdisjoint(dic1))

issubset(other)
other:Iterable
如果集合中的每个元素都在 other 之中,则返回 True
对应的运算符版本 set <= other 要求参数为集合

str1 = "132" 
list1 = [1, 4, "1", "2"] 
dic1 = {1:"1", 2:"2"} 
set1 = {"1", "2"} 
print(set1.issubset(str1)) # True 
print(set1.issubset(list1)) # True 
print(set1.issubset(dic1)) # False 
fset = frozenset(["1", "2"]) 
print(fset.issubset(str1)) 
print(fset.issubset(list1)) 
print(fset.issubset(dic1))

issuperset(other)
other:Iterable
如果 other 中的每个元素都在集合之中,则返回 True
对应的运算符版本 set >= other 要求参数为集合

str1 = "12" 
list1 = [1, "2"] 
dic1 = {1:"1", 2:"2"} 
set1 = {"1", "2", 1, 3} 
print(set1.issuperset(str1)) # True 
print(set1.issuperset(list1)) # True 
print(set1.issuperset(dic1)) # False 
fset = frozenset(["1", "2", 1, 3]) 
print(fset.issuperset(str1)) 
print(fset.issuperset(list1))
print(fset.issuperset(dic1))

union(*others)
others:Iterable
返回一个新集合,其中包含来自原集合以及 others 指定的所有集合中的元素(即并集)
对应的运算符版本 set | other | … 要求参数为集合

str1 = "12"
list1 = [1, "2"] 
dic1 = {1:"1", 2:"2"} 
set1 = {"1", "2", 1, 3} 
print(set1.union(str1, list1, dic1)) 
fset = frozenset(["1", "2", 1, 3]) 
print(fset.union(str1, list1, dic1))

intersection(*others)
others:Iterable
返回一个新集合,其中包含原集合以及 others 指定的所有集合中共有的元素(即交集)
对应的运算符版本 set & other & … 要求参数为集合

tr1 = "12" 
list1 = [1, "2"] 
dic1 = {"1":1, "2":2} 
set1 = {"1", "2", 1, 3} 
print(set1.intersection(str1, list1, dic1)) 
fset = frozenset(["1", "2", 1, 3]) 
print(fset.intersection(str1, list1, dic1))

difference(*others)
others:Iterable
返回一个新集合,其中包含原集合中在 others 指定的其他集合中
不存在的元素(即差集)
对应的运算符版本 set – other – … 要求参数为集合

str1 = "12" 
list1 = [1, "2"] 
dic1 = {"1":1, "2":2} 
set1 = {"1", "2", 1, 3} 
print(set1.difference(str1, list1, dic1)) 
fset = frozenset(["1", "2", 1, 3]) 
print(fset.difference(str1, list1, dic1))

symmetric_difference(other)
other:Iterable
返回一个新集合,其中的元素或属于原集合或属于 other 指定的其他集合,但不能同时属于两者(即对称差)
对应的运算符版本 set ^ other 要求参数为集合

str1 = "12" 
list1 = [1, "2"] 
dic1 = {1:"1", 2:"2"} 
set1 = {"1", "2", 1, 3} 
print(set1.symmetric_difference(str1)) # {1, 3} 
print(set1.symmetric_difference(list1)) # {"1", 3} 
print(set1.symmetric_difference(dic1)) # {"1", "2", 3, 2} 
fset = frozenset(["1", "2", 1, 3]) 
print(fset.symmetric_difference(str1)) 
print(fset.symmetric_difference(list1)) 
print(fset.symmetric_difference(dic1))

copy()
返回原集合的浅拷贝

set1 = {"1", "2", 1, 3} 
set2 = set1.copy() 
print(set2) 
fset1 = frozenset(["1", "2", 1, 3]) 
fset2 = fset1.copy() 
print(fset2)
  1. 仅 set 对象可用

set.update(*others)
others:Iterable
更新集合,添加来自 others 中的所有元素

str1 = "12" 
list1 = [1, "2"] 
dic1 = {"1":1, "2":2} 
set1 = {1, 3} 
set1.update(str1, list1, dic1) 
print(set1) # {1, 3, "1", "2"}

set.intersection_update(*others)
others:Iterable
更新集合,只保留其中在所有 others 中也存在的元素

str1 = "12" 
list1 = [1, "2"] 
dic1 = {"1":1, "2":2} 
set1 = {1, 3, "1", "2"} 
set1.intersection_update(str1, list1, dic1) 
print(set1) # {"2"}

set.difference_update(*others)
others:Iterable
更新集合,移除其中也存在于任意一个 others 中的元素

str1 = "12" 
list1 = [1, "2"] 
dic1 = {"1":1, "2":2} 
set1 = {1, 3, "1", "2"} 
set1.difference_update(str1, list1, dic1) 
print(set1)

set.symmetric_difference_update(other)
other:Iterable
更新集合,只保留存在于一方而非共同存在的元素

str1 = "12" 
set1 = {1, 3, "1", "2"} 
set1.symmetric_difference_update(str1) 
print(set1) # {1, 3}

set.add(elem)
将元素 elem 添加到集合中。如果元素已经存在,则没有影响

a = {1, 2, 3} 
a.add("hello world") 
print(a) # {1, 2, 3, 'hello world'}

set.remove(elem)
从集合中移除元素 elem。 如果 elem 不存在于集合中则会引发KeyError

a = {1, 2, 3, 4} 
a.remove(3) 
print(a) # a.remove(3)

set.discard(elem)
从集合中移除元素 elem。 如果 elem 不存在于集合中则不做任何操作

a = {1, 2, 3, 4} 
a.discard(3) 
print(a) 
a.discard(3)

set.pop()
从集合中移除并返回任意一个元素。如果集合为空则会引发
KeyError

a = {1, 2} 
elem1 = a.pop() 
print(elem1) 
print(a) 
elem2 = a.pop() 
print(elem2) 
print(a) #a.pop()

set.clear()
从集合中移除所有元素

a = {1, 2, 3, 4} 
a.clear() 
print(a)

5. 序列的索引和切片

六个标准的数据类型中是序列的有:字符串(String)、列表(List)、元
组(Tuple);通过索引和切片的方式可以访问序列中的元素

5.1 序列索引

string = "Hello 1牛3 Python" 
print(string[0]) # "H" 
print(string[-11]) # " " 
print(string[10]) # "P" 
print(string[-1]) # "n" 
print(string[4]) # "o" 
print(string[-7]) # " " 
print(string[6]) # "1" 

list1 = ["H", "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n"] 
print(list1[0]) 
print(list1[-11]) 
print(list1[10]) 
print(list1[-1]) 
print(list1[4]) 
print(list1[-7])

tup = ("H", "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n") 
print(tup[0]) 
print(tup[-11]) 
print(tup[10]) 
print(tup[-1]) 
print(tup[4]) 
print(tup[-7])

序列的长度:len(s)
返回对象的长度(元素个数)
s可以是序列(如string、bytes、tuple、list或range等)或集合(如dictionary、set或 frozen set等)

print(len("abcd")) # 4 
print(len([1, 2, 3, 4])) # 4 
print(len((1, 2, 3, 4)) # 4

5.2 序列切片

格式:[起始索引 : 结束索引 : 步长] (注意:所有符号都是英文输入法下的)
从序列中截取起始索引到结束索引的那部分子序列,包括起始索引,但不包括结束索引
当起始索引没有指定时,默认为0,当结束索引没有指定时,默认为序列的长度(前提:步长为正)
步长不写默认为1,代表切片时索引依次+1来选择元素,如果步长为2,则切片时索引依次+2来选择元素;如果步长为负数,则从后面开始切片,索引依次做减法
结束索引没有指定时,步长为负,结束索引默认为0;步长为正,结束索引默认为len()
切片默认左闭右开,方向向右为正;

string = "Hello 1牛3 Python" 
print(string[0: 2]) # "He" 
print(string[: 2]) 
print(string[1: 16]) 
print(string[1:len(string)]) 
print(string[1:]) 
print(string[:]) 
print(string[:1000]) 
print(string[-11: -9]) # " 1" 
print(string[2: 6]) # "llo " 
print(string[-9: -5]) # "牛3 P"
print(string[1: 10: 2]) 
list1 = ["H", "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n"]
print(list1[0: 2]) 
print(list1[-11: -9]) 
print(list1[2: 6]) 
print(list1[-9: -5]) 
tup = ("H", "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n") 
print(tup[0: 2]) 
print(tup[-11: -9]) 
print(tup[2: 6]) 
print(tup[-9: -5]) 
print(tup[: 2]) 
print(tup[: 11]) 
print(tup[:]) 
print(tup[::2]) 
print(tup[::-1]) 
print(tup[::-2])

String:正向索引下标与反向索引下标可以混用,步长方向与索引方向不一致则输出为空,步长默认方向为正;

string = "Hello 1牛3 Python"
print(string[0: 2]) # "He"
print(string[-2: 1]) 
print(string[-2: 1: 1]) 
print(string[-2: 1: -1])  # ohtyP 3牛1 oll
print(string[2: -1: 1])  # llo 1牛3 Pytho
print(string[: : -1])  #nohtyP 3牛1 olleH
print(string[-1: -len(string): -1])  #nohtyP 3牛1 olle
print(string[-1: -len(string)-1: -1])  #nohtyP 3牛1 olleH

索引会降维,切片不会降维——切不出为空列表,索引超出范围会报错,切片范围超出定义范围的部分为空(空字符≠(!=)空格):

list1 = ["H", "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n"]
print(list1[-3:-2])  # ['h']
print(list1[-3])  # h

print(string[-2: 1: -2])  # otP31ol  "Hello 1牛3 Python"
print(string[-2: 1: -1])  # ohtyP 3牛1 oll
print(string[-2: 1: 2])  # 
print(string[100])  #baocuo 
print(string[100: -1])  #

list1 = [123, "e", "l", "l", "o", " ", "1", "牛", "3", " ", "P", "y", "t", "h", "o", "n"] 
print(list1[0]) # 索引得到列表里面的一个元素, 123是整数类型 
print(list1[:1]) # 切片得到了列表的一个子列表, 它还是列表类型, 这个列表里面有一个整数类型的元素 123

5.3 del语句

del 语句在删除变量时,是解除变量对数据的引用,而不是直接删除数据,不是把内存地址删了,只是删除了引用,数据就变为了一个可回收的对象,然后内存会被不定期回收(-5~256——后续注意)

a = 2 # 对象 2 被变量 a 引用 
b = a # 对象 2 被变量 b 引用 
c = a # 对象 2 被变量 c 引用 
del a # 删除变量a,解除a对2的引用 
del b # 删除变量b,解除b对2的引用 
print(c) # 2 最终变量c仍然引用2 

a = [-1, 1, 66.25, 333, 333, 1234.5] 
del a[0] 
print(a) 

del a[2:4] 
print(a) 
del a[:] 
print(a) 
del a

5.4 赋值

id(object)
返回 object 的唯一标识符(内存地址)

Python中, 变量定义和赋值必须是同时进行的,比如当执行程序 a = 999 是先在内存中开辟一块空间来存放数据999,然后定义变量名a来指向这块空间的内存地址,方便我们使用变量值,所以变量名和值其实是一种引用的关联关系

严格来说,变量名本身没有类型,通常我们所说的变量类型指的是值的数据类型

var1 = 999 
print(type(var1)) # <class 'int'> 
var1 = "999" print(type(var1)) # <class 'str'>

通过内置函数id()获取变量地址时,实际是返回了值的地址:

var1 = 256 
print(id(256)) 
print(id(var1)) # 同上 

var2 = -5 
print(id(-5)) 
print(id(var2)) # 同上 

var3 = 257 
print(id(257))
print(id(var3)) # 不一样 

var4 = -6 
print(id(-6)) 
print(id(var4)) # 不一样

为了节省内存空间,解释器做了优化,如果直接执行程序文件,相
同值的变量会引用自同一个对象,而在交互式窗口运行则可以看到
区别

小整数对象池:
Python 为了优化速度,避免整数频繁申请和销毁
内存空间,把范围在 [-5, 256] 之间的数字放在提前建立好的小整
数对象池里面,不会被垃圾回收,在这范围内的数值如果相等,地
址也就相同,因为使用的都是同一个对象

a = 257 
b = 257 
print(id(a)) 
print(id(b)) 
a = 256 
b = 256 
print(id(a)) 
print(id(b)) 
a = -5 
b = -5 
print(id(a)) 
print(id(b)) 
a = -6 
b = -6 
print(id(a)) 
print(id(b))

一个值可以被多个变量名引用,当变量值的引用计数(即值被关联的次数)为0时,可认定为该值不可用,那么Python的垃圾回收机制会收回所占用的内存空间

a = 999 # a = [1, 2, 3] 
b = 999 # b = [1, 2, 3]
c = a 
# 变量a、c都指向第一个999, 引用计数为2 
print(id(a)) 
print(id(c)) 
# 变量b指向第二个999, 引用计数为1 
print(id(b)) 

del a # 解除a的引用, 第一个999的引用计数为-1, 为1 
print(id(c)) # c还是指向第一个999 
c = b # 解除c的引用, 重新指向第二个999, 则第一个999的引用计数再-1, 为0, 被回收 
# b、c都指向第二个999, 引用计数+1, 为2 
print(id(b)) 
print(id(c))

当一个可变类型的数据被多个变量名引用时,如果对该原数据进行修改,那么它所有引用都会改变

a = [1, 2, 3] 
b = [1, 2, 3] 
c = a 

# 变量a、c都指向第一个[1, 2, 3], 引用计数为2 
print(id(a)) 
print(id(c)) 
# 变量b指向第二个[1, 2, 3], 引用计数为1 
print(id(b)) 

a.append(4) 
print(a) 
print(c) 
print(b)

6. 浅拷贝&深拷贝

Python 中的赋值语句不复制对象,只是建立引用关联,对于可变数据,有时我们不希望直接对它进行修改,因为这可能会导致一些意外的情况发生,所以我们就可以把它copy一份,对它的副本进行操作

这种copy操作又分为浅层copy和深层copy,我们所学的 list.copy()、dict.copy()、set.copy() 属于浅层copy。在copy模块中,提供了通用的浅层和深层copy操作

6.1 浅拷贝

如果浅拷贝对象是不可变数据类型(复合类型数据只要最外侧的类型不可变即可),那么和赋值语句等效(没有拷贝的意义)

import copy 
tup1 = (991, "abc") 
tup2 = copy.copy(tup1) # 浅拷贝
# tup2 = tup1 
print(tup1) 
print(tup2) 
print(id(tup1)) 
print(id(tup2)) 

tup3 = (991, "abc", []) 
tup4 = copy.copy(tup3) # 浅拷贝 
print(tup3) 
print(tup4)
print(id(tup3)) 
print(id(tup4)) 
print(id(tup3[-1])) 
print(id(tup4[-1]))

如果浅拷贝对象是可变数据类型(复合类型数据只要最外侧的类型可变即可),那么浅拷贝会把该对象复制一份,但是该对象中的其他所有元素(包括复合类型数据中的元素)仍为引用关系

import copy 
lis1 = [991, "abc", (9, 993), [994, 995], [888, 887], {"name": "Tom"}, (996, [997, 998]), (888, (886, 886))] 
lis2 = copy.copy(lis1) # 浅拷贝 
print(id(lis1)) 
print(id(lis2)) 
lis1.append(9) 
print(lis1) 
print(lis2) 
print("索引0对应的id", id(lis1[0])) 
print("索引0对应的id", id(lis2[0])) 
print("索引1对应的id", id(lis1[1]))
print("索引1对应的id", id(lis2[1])) 
print("索引2对应的id", id(lis1[2])) 
print("索引2对应的id", id(lis2[2])) 
print("索引3对应的id", id(lis1[3])) 
print("索引3对应的id", id(lis2[3])) 
print("索引4对应的id", id(lis1[4])) 
print("索引4对应的id", id(lis2[4])) 
print("索引5对应的id", id(lis1[5])) 
print("索引5对应的id", id(lis2[5])) 
print("索引6对应的id", id(lis1[6])) 
print("索引6对应的id", id(lis2[6]))
print("索引7对应的id", id(lis1[7])) 
print("索引7对应的id", id(lis2[7])) 
print(id(lis1[6][-1])) 
print(id(lis2[6][-1])) 
print(id(lis1[7][-1])) 
print(id(lis2[7][-1])) 

lis1[3] = [994] 
print(lis1) 
print(lis2) 
lis1[3].append(999) 
print(lis1) 
print(lis2) 
lis1[4].append(886) 
print(lis1) 
print(lis2) 
lis1[5].update(age=18) 
print(lis1) 
print(lis2) 
lis1[6][-1].pop()
print(lis1) 
print(lis2)

6.2 深拷贝

如果深拷贝对象是不可变数据类型(复合类型数据还需确保其中的所有元素不可变),那么和赋值语句等效(没有拷贝的意义)

import copy 
tup1 = (991, "abc") 
tup2 = copy.deepcopy(tup1) # 深拷贝 
# tup2 = tup1 
print(tup1) 
print(tup2) 
print(id(tup1)) 
print(id(tup2)) 
tup3 = (991, "abc", []) 
tup4 = copy.deepcopy(tup3) # 深拷贝 
print(tup3) 
print(tup4) 
print(id(tup3)) 
print(id(tup4)) 
print(id(tup3[0])) 
print(id(tup4[0])) 
print(id(tup3[1])) 
print(id(tup4[1])) 
print(id(tup3[-1]))
print(id(tup4[-1]))

如果深拷贝对象是可变数据类型或者其中的复合类型数据中有可变的元素,那么深拷贝会把该对象复制一份

import copy 
lis1 = [991, "abc", (9, 993), [994, 995], [888, 887], {"name": "Tom"}, (996, [997, 998]), (888, (886, 886))] 
lis2 = copy.deepcopy(lis1) # 深拷贝 
print(id(lis1)) 
print(id(lis2)) 
lis1.append(9) 
print(lis1)
print(lis2) 
print("索引0对应的id", id(lis1[0])) 
print("索引0对应的id", id(lis2[0])) 
print("索引1对应的id", id(lis1[1])) 
print("索引1对应的id", id(lis2[1])) 
print("索引2对应的id", id(lis1[2])) 
print("索引2对应的id", id(lis2[2])) 
print("索引3对应的id", id(lis1[3])) 
print("索引3对应的id", id(lis2[3])) 
print("索引4对应的id", id(lis1[4])) 
print("索引4对应的id", id(lis2[4])) 
print("索引5对应的id", id(lis1[5])) 
print("索引5对应的id", id(lis2[5])) 
print("索引6对应的id", id(lis1[6])) 
print("索引6对应的id", id(lis2[6])) 
print("索引7对应的id", id(lis1[7])) 
print("索引7对应的id", id(lis2[7])) 
print(id(lis1[6][-1])) 
print(id(lis2[6][-1])) 
print(id(lis1[7][-1])) 
print(id(lis2[7][-1]))

对于其中的元素分别递归的去适用前两点规则

lis1[3].append(999) 
print(lis1) 
print(lis2) 
lis1[5].update(age=18) 
print(lis1) 
print(lis2) 
lis1[6][-1].pop() 
print(lis1) 
print(lis2)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年5月11日 上午11:26
下一篇 2022年5月11日

相关推荐