python 基础 详细,python 基础入门

大家好,小编来为大家解答以下问题,python 基础 详细,python 基础入门,现在让我们一起来看看吧!

python知识点大全,基础阶段一篇到底

持续更新中........一、CPython二、 基本语法2.1 print输出2.2 变量、常量与垃圾回收机制2.2.1 变量2.2.2 常量2.2.3 内存指向2.2.4 垃圾回收机制垃圾回收机制原理分析2.3 input输入三、数据类型3.1 int整型与float浮点型3.1.1 int与str相互转换3.2 str字符串3.2.1 str的切片3.2.2 str的常用方法3.2.3 字符串逻辑判断相关3.2.4 str转list3.3 list列表3.3.1 list的切片3.3.2 list的增删改查3.3.3 list其他常用方法3.3.4 列表嵌套练习3.3.5 逻辑判断相关3.3.6 深浅copy3.3.7 列表转字符串、集合3.4 元组3.4.1 元组常用方法3.4.2 元组的多种定义方式3.5 字典3.5.1 增加属性3.5.2 删除属性或字典3.5.3 修改属性3.5.4 查找属性3.6 集合3.6.1 集合的增删改查3.6.2 求交并集3.6.3 利用集合实现列表去重3.7 补充3.7.1 可变与不可变类型3.7.2 初识编码3.7.3 bool数据类型3.8 格式化输出3.8.1 模拟进度条四、运算符4.1 常见的运算符4.2 is与==4.3 其他五、 流程控制5.1 分支结构if5.1.1 三元运算5.2 循环结构for5.2.1 continue与break5.2.2 语句5.2.3 实现99乘法表5.3 循环结构while5.3.1 语句5.3.2 利用while计算5.3.3 与for的异同六、字符编码6.1 字符编码的应用七、文件操作7.1 资源回收与with上下文管理7.2 文件的操作模式7.2.1 读7.2.2 写7.2.3 追加7.2.4 指定取多少字符的内容7.3 更改文件内指针(光标)7.4 文件内容修改/重命名八、函数8.1 名称空间与作用域8.1.1 global关键字8.1.2 nonlocal关键字8.2 函数对象8.3 闭包函数8.4 装饰器8.4.1 有参数的装饰器8.5 迭代器8.6 生成器8.7 递归函数8.8 匿名函数8.9 内置函数8.9.1 max函数8.9.2 sorted函数8.9.3 map函数8.9.4 filter函数8.9.5 print函数8.9.6 数学运算8.9.7 其他内置函数8.10 补充:高阶函数九、模块9.1 from...import9.2 模块查找十、包十一、常用模块--后续完善11.1 time、datetime模块11.2 random模块11.3 os模块11.x json模块后续完善.....十二、面向对象12.1 初识12.1.1 补充12.2 __init__方法12.3 小案例12.4 魔术方法12.5 隐藏属性12.6 property装饰器12.7 继承12.7.1 单继承的属性查找12.7.2 多继承的属性查找12.7.3 Mixin12.7.4 调用父类中的方法12.8 多态与鸭子类型12.9 classmethod与staticmethod12.10 反射

持续更新中…

更新日志:

2023-09-25 对部分代码片的缩进问题进行更正,后续不在进行变更了。2023-04-04 修改了集合数据类型删除的笔误。2022/10/4 更新了一些写错,以及上传CSDN造成的格式/排版/错别字等错误。2022/9/8 常用模块章节因为时间关系,后续需要自行查阅相关资料。2022/9/3 常用模块章节补充了os模块

声明:

本文采用大白话+个人理解的形式进行介绍,尽可能的快速了解,如 举的例子、理解的不对或者不专业、不恰当,请务必狠狠指出[doge]

卫星:liuyu719719 欢迎讨论交流

一、CPython

什么是CPython?

CPython是特指C语言实现的Python,就是原汁原味的Python。之所以使用CPython这个词,是因为Python还有一些其它的实现,比如Jython,就是Java版的Python,还有烧脑的PyPy,使用Python再把Python实现了一遍。

CPython

当我们从Python官方网站下载并安装好Python 3.5后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器,CPython是使用最广的Python解释器。

IPython
  IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。好比很多国产浏览器虽然外观不同,但内核其实都是调用了IE,CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。
PyPy
  PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。
  绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点。
Jython
  Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython
  IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

编译型与解释型编程语言

编译型相当于厨师直接做好一桌子菜,顾客来了直接开吃。解释型就像吃火锅,厨师把菜洗好,顾客需要自己动手边煮边吃。所以,效率上来说解释型语言自然比不过编译型语言,当然也不是绝对了。

Python(这里主要是指CPython)并不是严格的解释型语言,因为 Python 代码在运行前,会先编译(翻译)成中间代码,每个 .py 文件将被换转成 .pyc 文件,.pyc 就是一种字节码文件,它是与平台无关的中间代码,不管你放在 Windows 还是 Linux 平台都可以执行,运行时将由虚拟机逐行把字节码翻译成目标代码。

我们安装Python 时候,会有一个 文件,它就是 Python 解释器,你写的每一行 Python 代码都是由它负责执行,解释器由一个编译器和一个虚拟机(PVM)构成,编译器负责将源代码转换成字节码文件,而虚拟机负责执行字节码,所以,解释型语言其实也有编译过程,只不过这个编译过程并不是直接生成目标代码,而是中间代码(字节码),然后再通过虚拟机来逐行解释执行字节码。

一般认为,Python与Java都是解释型语言,只是不那么纯粹。也可以认为它们是先编译再解释的编程语言。并非所有高级语言都是要么是编译型语言,要么就是解释型语言。

python解释器、pycharm、IDE到底是什么?

IDE是辅助程序员开发的应用软件。pycharm是IDE中用于辅助python程序员的软件之一。CPU不能直接处理Python语言,只能处理机器语言,所以python解释器,就是把python语言翻译成计算机CPU能听懂的机器指令语言。

解释器、pycharm、的下载及配置本文略。

二、 基本语法

2.1 print输出

函数名:

print()

作用:

用于控制台/命令行打印输出

代码示例:

print('你好,我是print')   #输出结果:你好,我是print
print(998)    #输出结果:998

附:

本小节仅为初识print,更多用法请前往“内置函数”章节

2.2 变量、常量与垃圾回收机制

2.2.1 变量

什么是变量:

变量就是可以变化的量,量指的是事物的状态,比如人的年龄、性别,游戏角色的等级、金钱等等

为什么要有变量:

程序执行的本质就是一系列状态的变化,“变”是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程序执行时状态,以及状态的变化。

如何使用变量:

先定义,后使用

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

变量名 = 值

变量名:相当于门牌号码,指向值所在的内存地址,是访问到值的唯一方式。

= : 等号为赋值符号,用来将变量值的内存地址绑定给变量名

: 变量的值,就是我们存储的数据。

代码示例:

name = 'liuyu'
age = 22

变量的命名规范:

变量名只能是字母、数字或下划线的任意组合

变量名的第一个字符不能是数字

关键字不能声明为变量名,常用关键字如下

['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from','global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']

变量的命名风格

驼峰体

userName = 'liuyu'
userAge = 22

纯小写下划线(在python中,变量名的命名推荐使用该风格)

user_name = 'liuyu'
user_age = 22

变量具有的三大特性

id,反应的是变量在内存中的唯一编号,内存地址不同id肯定不同。type,变量值的类型。value,变量值。

x='liuyu'
print(id(x),type(x),x)
	# 输出结果:
	呵呵40 <class 'str'>  liuyu
    # 内存地址     属于str字符串类  内存地址对应的值

可以多个变量一起赋值

a,b,c = 1,2,3   
print(a,b,c)
	# 输出结果: 1 2 3
    
a,b,c = [1,2,3]   # 列表数据类型,后续介绍
print(a,b,c)    
	# 输出结果: 1 2 3    #拿到的是列表内对应索引的值
    
a,b,c = {'a':'A','b':'B','c':'C'}  # 字典数据类型,后续介绍
print(a,b,c)
    # 输出结果: a b c    #拿到的是字典的Key,不是value。
2.2.2 常量

什么是常量:

常量指在程序运行过程中不会改变的量比如:圆周率 3.141592653…

如何使用常量:

在Python中没有一个专门的语法定义常量,约定俗成是用全部大写的变量名表示常量。如:PI=3.14159。所以单从语法层面去讲,常量的使用与变量完全一致。

2.2.3 内存指向
name = 'liuyu'

在这段代码中,我们定义了变量name,随后赋值为“liuyu”,那么我们的name和值是如何存储的呢?

内存中分为栈区和堆区。栈区用来存放变量指向的内存地址,这个内存地址相当于值的门牌号,可以通过这个门牌号找到堆区的值。

name2 = 'liuyu'

此时重新定义一个变量name2,值也为’liuyu’,那么此时内存中是如何存储的呢?

因为liuyu这个值,还在被name变量所指向,所以还存在内存中。

当name2变量的值与name相同时,不再重新开辟空间,而是直接将name2指向name的值。

			  栈区				堆区
name ---- name=0xfff001 ---- 0xfff001='liuyu'
		                        |   
		                        |
name2 ---- name=0xfff001 --------
2.2.4 垃圾回收机制

解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉。

那什么样的变量值是没有用的呢?

由于变量名是访问到变量值的唯一方式,所以当一个变量值不再关联任何变量名时,我们就无法再访问到该变量值了,该变量值就是没有用的,就应该被当成一个垃圾回收。

什么是垃圾回收机制

垃圾回收机制(简称GC)是Python解释器自带一种机,专门用来回收不可用的变量值所占用的内存空间

为什么要有垃圾回收机制

程序运行过程中会申请大量的内存空间,而对于一些无用的内存空间如果不及时清理的话会导致内存使用殆尽(内存溢出),导致程序崩溃,因此管理内存是一件重要且繁杂的事情,而python解释器自带的垃圾回收机制把程序员从繁杂的内存管理中解放出来。

垃圾回收机制原理分析

Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题,并且通过“分代回收”(generation collection)以空间换取时间的方式来进一步提高垃圾回收的效率。

引用计数标记清除分代回收

了解即可,这个不需要程序员自己去操作。

2.3 input输入

函数名:

input('提示信息')
# 运行该代码,会弹出'提示信息',然后等待输入数据,输入之后该函数会将输入的数据返回,所以应该定义变量去接收,变量接收的数据为字符串类型

作用:

用于获取输入的信息

代码示例:

str1 = input("你叫什么名字?")  #输入:liuyu
str2 = input("你几年几岁了")  #输入: 22
print("你是"+str1,"今年"+str2)   #打印字符串拼接之后的结果:你是liuyu 今年22  # 字符串拼接后续有介绍

注意:

返回的数据为字符串数据类型(数据类型详情见下一章节),如果有数字计算,一定要转换数据格式。

三、数据类型

3.1 int整型与float浮点型

int整型

作用:

用来记录人的年龄,出生年份,学生人数等整数相关的状态 。

定义:

age=18

birthday=1990

student_count=48

float浮点型

作用:

用来记录人的身高,体重,薪资等小数相关的状态

定义:

height=172.3

weight=103.5

salary=15000.89

应用:数学计算

height=172.3
height2 = 180
print(height+height2)
# 输出结果: 352.3
3.1.1 int与str相互转换

在有些情况时,可能会需要将字符串1与字符串2进行数值相加,但因为是字符串数据类型,最后的结果是拼接而非数值相加。

所以我们可以利用数据类型之间的转换,将str转int,那么反过来,我们也会有很多种情况,是需要将int转成str的。

int转str

函数名str()

num = 998
num_str = str(num)
print(num_str,type(num_str))  # 998 <class 'str'>

str转int

函数名int()

str1 = '100'
num = int(str1)
print(num,type(num)) # 100 <class 'int'>

3.2 str字符串

作用:

用来记录人的名字,家庭住址,性别等描述性质的状态

定义:

name = 'liuyu'
address = '上海市徐汇区'
sex = '男'

字符串的特点:

使用 单引号双引号三引号 包裹起来的文本。

另外,三引号可以折行

a = 'AAA'  #单引号
b = "BBB"  #双引号

# 三引号
abcd = """
	床前明月光,
	你是头上慌。			
	"""         			                     
print(abcd) 
# 输出结果:
#	床前明月光,
#	你是头上慌。

字符串的应用

字符串可以拼接

a = '加油'	 		
b = '吧'
c = a + b   #字符串拼接
print(c)   # 输出结果: 加油吧

字符串可以做运算

print('坚强'*8)   # 输出结果:坚强坚强坚强坚强坚强坚强坚强坚强

字符串可以嵌套

第一种

print("my name is '迪迦'")  #输出结果: my name is '迪迦'

第二种

print('my name is \'迪迦\'')   #输出结果: my name is '迪迦'

另外,双引号可以内嵌单引号的内容,同时单引号也可以内嵌双引号的内容。

print("我真的'栓Q'。")  #输出结果:我真的'栓Q'。

也可以使用“\”反斜杠,来屏蔽后面字符的特殊含义,使其变成普通的引号。

print('\'测试\'')  #输出结果:'测试'
3.2.1 str的切片

作用:

在字符串中,切取自己想要的“片段”,就是切片。

格式:

取单个元素

str[索引]
# 索引的值是根据str的最小元素位数来定义的。

取一段元素

str[起始索引:结束索引:步长]

步长: 表示每隔多少个元素取值

特点:

顾头不顾腚,当切片时最后一位不取,会取最后一位之前的。

引子:

#这是个字符串,他的最小元素是 a  b  c  d 
a = 'abcd'  
	 #a在整个字符串从左到右的第一位  b在第二位  c在第三位  d在第四位
 print(a[1])     #输出结果为  b

疑问:

明明我要输出的是a这个字符串的第一位元素a啊,为什么最后结果是第二位元素b啊。

答:

因为str切片是按照索引的,而索引的值是从0开头的,而我们刚刚是从1开头的,所以要想print的结果为a,则需要减一,即a的索引为0、b的索引为1、c的索引为2、d的索引为3如果一个字符串特别长,又不想从前往一直数到末尾,-1可以表示最后一位

代码示例:

a = 'abcd'  
print(a[0])   #输出结果为   a
print(a[3])   #输出结果为   d

str = '你好特别,就是么有钱,我们不合适'
str1 = str[0] + str[2] + str[7]   
print(str1)    #输出结果:你特么

learn = '学着好特么累啊你还学不'
learn2 = learn[0] + learn[-1]       #取第一位和最后一位,并拼接为一个字符串。
print(learn2)          #输出结果:学不

以上为单个切片取值,那么我要取一小段或倒着取该怎么操作呢。

learn = '学着好特么累啊你还学不'
print(learn[2:-1])   #输出结果:好特么累啊你还学

注:

因为切片有个规则顾头不顾尾,即取起始索引,到结束索引之前那一段的内容,但不包括结束索引的。

所以在上述案例中,最后以为的"不"字,并没有通过切片取到。

要想获取到最后以为,可以不写结束索引,如下

learn = '学着好特么累啊你还学不'
print(learn[2:])
#输出结果: 好特么累啊你还学不

步长的运用

learn = '学着好特么累啊你还学不' 
print(learn[2:7:2])   # 最后一个2为步长,表示每隔2个再取值。
#输出结果:好么啊    

print(learn[3:0:-1])   #当步长为‘-1’时为倒着取,所以开始索引要比结束索引靠后,并且0这一位因为变成了末尾,所以取不到,只能取到索引为1的。
#输出结果:特好着 
   
print(learn[5])   #取单个时,不会受到‘顾头不顾腚’规则的影响
#输出结果:累
3.2.2 str的常用方法

汇总一览:(点击可进行跳转)

注:

str字符串为不可变数据类型,所以,本章节所有的字符串方法,并不会对原数据有任何修改,str1 为原字符串,str2 为函数/方法处理之后返回的新值。

str类型转bool类型

函数名:

bool(string)

作用:

将字符串转为布尔值字符串为空,则转为False,不为空转为True,主要用于if判断。

代码示例:

str1 = 'a'
print(bool(str1))
	#输出结果:True
str1 = ' '
print(bool(str1))   
	#输出结果:True   因为空格也是内容
str1 = ''
print(bool(str1))   
	#输出结果:False

附:

int类型也可以使用bool方法进行判断,0为False,其他数值为True

使用Join方法进行字符串拼接

函数名:

'连接符'.join()

作用:

将多个字符串拼接成一个字符串。

在python中不推荐使用字符串拼接,推荐使用join

而有些语言会推荐使用字符串拼接的方式,比如JavaScript

代码示例:

a = 'www'
b = 'baidu'
c = 'com'

new_str = '.'.join([a,b,c])
print(new_str)   #输出结果: 

capitalize 首字母大写

函数名:

string.capitalize()

作用:

返回字符串首字母大写对调用该方法的字符串,没有任何影响。

代码示例:

str1 = 'liu yu'
print(str1.capitalize())  # 输出结果: Liu yu

该方法会返回处理好的字符串(首字母大写),并不会对原字符串产生影响。

upper 全大写

函数名:

string.upper()

作用:

返回字符串的全大写

代码示例:

str1 = 'liu yu'
str2 = str1.upper()
print(str2)  # 输出结果: LIU YU

lower 全小写

函数名:

string.lower()

作用:

返回字符串的全小写

代码示例:

str1 = 'LIU YU'
str2 = str1.lower()
print(str2)   # 输出结果: liu yu

swapcase 大小写反转

函数名:

string.swapcase()

作用:

返回字符串的大小写反转

代码示例:

str1 = 'I Love You'
str2 = str1.swapcase()
print(str2)   # 输出结果:i lOVE yOU

title以空格或特殊字符分开的首字母大写

函数名:

string.title()

作用:

返回字符串以空格或特殊字符分开的首字母大写

代码示例:

str1 = 'i love you'
str2 = str1.title()
print(str2)   # 输出结果: I Love You

str1 = 'i_love_you'
str2 = str1.title()
print(str2)   # 输出结果: I_Love_You

center 居中

函数名:

string.center()

代码示例:

str1 = 'AA'
str2 = str1.center(4,'-')
print(str2)   #输出结果: -AA-

center的第一个参数,是生成新字符串的最大长度,随后将调用该方法的字符串,也就是str1居中,剩余的空间用第二参数,也就是’-'填充。

startswith 以…开头,支持切片判断…

函数名:

string.startswith('xxx',起始索引,结束索引)

作用:

用于判断一个字符串是否以某某某开头。也可以利用字符串切片再判断是否以某某某开头

代码示例:

str1 = 'GG爆,童话里做英雄'
str2 = str1.startswith('g')  # 区分大小写,所以结果应该是False
print(str2)	
#输出结果: False



str1 = 'GG爆,童话里做英雄'
str2 = str1.startswith('童',4,7)  #可进行切片判断
print(str2)
#输出结果: True

endswith 以…结尾

函数名:

string.endswith('xxx')

作用:

用于判断该字符串是否以某某某结尾

代码示例:

str1 = 'i love you'
print(str1.endswith('you'))
#输出结果: True

find 查找字符串的元素并返回索引

函数名:

('xxx',起始索引,结束索引)

作用:

用于查找字符串中的元素,返回值为索引。当没找到元素时,返回值为-1支持切片查找

代码示例:

str1 = 'emo时间到'
find_index = ('o')
print(find_index)  #输出结果:  2

str1 = 'emo时间到'
find_index = ('r')
print(find_index) #输出结果:  -1  当find未找到元素时,返回值为-1

str1 = 'emo时间到'
find_index = ('时',2,-1)
print(find_index)   #输出结果:  3   支持切片查找(提高效率)

strip 去掉首尾的空格或特殊字符

函数名:

string.strip('需要去掉的特殊字符,默认为空格')

作用:

返回字符串去掉首尾空格。返回字符串去掉首尾特殊字符。

代码示例:

str1 = ' liu yu '
print(str1.strip())   #输出结果:liu yu

str1 = '--liu-yu--'
print(str1.strip('-'))  #输出结果:liu-yu

因为strip方法只去掉首尾的特殊字符,但是中间的不管。

如果真的想把所有的空格或者特殊字符都去掉,可以写一个函数,后续直接调用

def remove_spaces_str(data,char):
    if type(data) is str:    #判断是否为字符串
        ret = ''    #定义一个‘空’变量
        for i in data:    #挨个循环
            ret = ret + i.strip(char)
        return  ret
    else:
        return '请输入字符串'
    
str1 = '--liu-yu--'
str2 = remove_spaces_str(str1,'-')  #参数1:需要操作的字符串。 参数2:需要删除的特殊字符
print(str2)          #输出结果为:liuyu

count 计算元素出现的次数

函数名:

string.count('xxx')

作用:

用于计算元素出现的次数,这个元素可以是多个。

代码示例:

str1 = '萝卜蹲萝卜蹲,萝卜蹲完胡萝卜蹲'
print(str1.count('萝卜'))  #输出结果为: 4
print(str1.count('蹲'))  #输出结果为:4

split 以…分割

函数名:

string.split("xxx")

作用:

以xxx分割,分割出来的元素组成列表并返回。

代码示例:

str1 = '高清:无码:葫芦娃&儿'
str2 = str1.split(":")
print(str2)      #输出结果:['高清', '无码', '葫芦娃&儿']  格式为列表

split方法还有一个 maxsplit 参数,用于控制最大切片次数,示例如下:

str1 = 'a:b:c:d:e:f:g'
print(str1.split(':',maxsplit=2))  # 输出结果:['a', 'b', 'c:d:e:f:g']

format 格式化字符串

函数名:

string.format()

作用:

用于格式化字符串

三种用法:

利用位置进行替换利用索引进行替换利用关键字进行替换

代码示例:

#利用位置进行替换
test1 = '每个人身上都有{},让我为你唱{}'.format('毛毛','毛毛')

#利用索引进行替换
test2 = '每个人身上都有{0},让我为你唱{1}'.format('毛毛','maomao')

#利用关键字进行替换
test3 = '你叫什么叫,{sha}'.format(sha='不服你打我')

print(test1)  	#输出结果:  每个人身上都有毛毛,让我为你唱毛毛
print(test2)	#输出结果:  每个人身上都有毛毛,让我为你唱maomao
print(test3)	#输出结果:  你叫什么叫,不服你打我

replace 字符串替换

函数名:

string.replace('旧字符','新字符','替换到第几次停止')

作用:

返回字符串替换之后的

代码示例:

s = '主播你好我是小学生可以给我磕个头吗'
s1 = s.replace('小学生','主播')    #将小学生替换为主播
print(s1)     #输出结果为:    主播你好我是主播可以给我磕个头吗 

s2 = s1.replace('主播','小学生',1)   #将主播替换为小学生,只替换一次
print(s2)     #输出结果为:	小学生你好我是主播可以给我磕个头吗	

len 计算元素个数

函数名:

len(str)

作用:

返回字符串的元素个数

代码示例:

test = 'abcd'
print(len(test))   #输出结果为: 4

test2 = ['1','2','4']
print(len(test2))   #输出结果为: 3

max 返回最大元素

函数名:

max(str)

作用:

返回字符串中最大的元素,应该是按照ascii码来对比的,a-z,z最大。

ascii码对照表

同时也可用于列表,返回列表中最大的元素

代码示例:

test = 'azbjcd'
print(max(test))   #输出结果为: z   
# ascii码对比 a:97  z:122,所以z最大。


# 该方法列表同样使用,只要是可迭代数据类型都可以,这些概念后续会介绍。
test2 = ['1','2','98','4']
print(max(test2))   #输出结果为: 98


# 当列表内字符串的元素为多个时,判断大小的依据为首个元素的大小。
lis = ['aby','bcf','cAA']
print(max(lis))
#  97+98+121
#  98+99+102
#  99+65+65   由于c的ascii码为99,后续的65虽然小于前面,但是开头大,就是大。

# 输出结果为:cAA

min返回最小的元素

函数名:

min(str)

作用:

与max()相反

代码示例:

test = 'azbjcd'
print(min(test))    #输出结果为: a
test2 = ['1','2','98','4']
print(min(test2))   #输出结果为: 1
3.2.3 字符串逻辑判断相关

数据类型分为:

str字符串、list列表、dict字典、tuple元组 、int数字

后续可通过type()函数,来进行判断是哪个数据类型,从而做出不同的操作。

应用:

该案例中使用了for循环,需要先去了解for循环,再回来观看。

#计算字符串中数字、字母、空格、特殊字符出现的次数
s = 'd.an123slfn a.ndwlkand312321k an nkl/klraw'
number = 0 #数字
alpha = 0 #字母
space = 0 #空格
other = 0 #其他
for i in s:
    if i.isdigit():      #判断该字符串是否为数字
        number  += 1
    elif i.isalpha():   #判断该字符串是否为字母
        alpha += 1
    elif i.isspace():    #判断该字符串是否为空格
        space += 1
    else:
        other  += 1    
print(number,alpha,space,other)
3.2.4 str转list

两种方式:

第一种,利用内置函数list()

str1 = '123'
lis = list(str1)
print(lis)  # ['1', '2', '3']

第二种,利用字符串方法split

str1 = '1-2-3'
lis = str1.split('-')
print(lis)  # ['1', '2', '3']

3.3 list列表

作用:

列表可以⼀次性存储多个数据,且可以为不同数据类型,如:⼀个班级100位学⽣,每个⼈的姓名都要存储,那就需要声明100个变量,而现在有个数组,我们可以存入到一个数组里

定义:

student_list = ['张三','李四','王五','马六',]

列表的特点:

有序,可更改,可以有重复的元素。

可以存储多个不同数据类型的数据,每个数据元素之间用逗号隔开,列表整体为中括号包裹。

hobby_list = ['吃饭','睡觉','打游戏']
print(hobby_list)  #输出结果: ['吃饭', '睡觉', '打游戏']
3.3.1 list的切片

列表切片

与字符串的切片基本上大同小异。

嵌套切片

lis = ['大白菜鸡毛菜','通心菜','油麦菜',['绿的菜白的菜','什么菜炒什么菜,']]
print(lis[0])       #输出结果: 大白菜鸡毛菜
print(lis[3])		#输出结果: ['绿的菜白的菜', '什么菜炒什么菜,']
print(lis[3][1])    #输出结果: 什么菜炒什么菜

附:

print(lis[3][1])此处需要分步,第一步 list[3] = [‘绿的菜白的菜’,‘什么菜炒什么菜,’]第二步,lis[3][1] = [‘绿的菜白的菜’,‘什么菜炒什么菜,’][1] = 什么菜炒什么菜

# 练习,下列会输出什么
 print(lis[3][1][1])     #结果:么
3.3.2 list的增删改查

汇总一览:

注:列表为可变数据类型,所以很多方法都时在原列表的基础之上进行修改的。

append添加列表元素

格式:

list.append()

与str类型不同,list的方法有很多都是作用于原列表之上,对原数据进行更改,如append,就是在调用该方法的列表中,添加新的元素(值)

代码示例:

lis = ['xixihaha']
lis.append('chichihehe')
print(lis)   #输出结果:['xixihaha', 'chichihehe']  

insert插入元素

格式:

list.insert(index,data)
# 索引为必选参数,表示数据插入到指定索引处

代码示例:

lis = ['嘻嘻哈哈', '吃吃喝喝']
lis.insert(1,'睡觉觉')    # 将数据插入到所以为1的位置
print(lis)
#输出结果:['嘻嘻哈哈', '睡觉觉', '吃吃喝喝']

extend迭代插入最小元素

格式:

list.extend(data)

代码示例:

lis = ['嘻嘻哈哈', '吃吃喝喝']
lis.extend('睡觉觉')
print(lis)
#输出结果:['嘻嘻哈哈', '吃吃喝喝', '睡', '觉', '觉']

lis.extend(['刷抖音'])
print(lis)
#输出结果:['嘻嘻哈哈', '吃吃喝喝', '睡', '觉', '觉', '刷抖音']

pop按照索引删除列表元素

格式:

([index])
	# 中括号表示可选参数

默认删除末尾的元素,当传入index参数时,删除该索引的元素

该方法会返回被删除的元素

代码示例:

lis = ['a','b','c','d']
str1 = ()   #索引为空默认删除最后一位,该方法会返回被删除的元素。
str2 = (0)   #删除索引为0的元素
print(lis,str1,str2) #输出结果: ['b', 'c'] d a

remove按照元素删除列表元素

格式:

list.remove('元素值')

该方法与pop不同,remove没有返回值。

代码示例:

lis = ['a','b','c','d']
str1 = lis.remove('a')
print(str1,lis)

clear清空列表所有元素

lis.clear()
print(lis)   #返回结果为:[]

del 删除列表

格式:

del list
# 或
del list[起始索引:结束索引]

代码示例:

del lis
print(lis)  #报错,因为没有lis这个列表了

lis = ['a','b','c','d']
del lis[2:]   #索引2及以后的都删除
print(lis)   #['a', 'b']

利用重新赋值的方式,修改列表

格式:

list[索引] = 值
# 或
list[起始索引:结束索引] = 值

代码示例:

lis = ['a','b','c','d']
lis[0] = 'ABC'  # 将列表的0号索引的元素修改为 ‘ABC’
print(lis)  # ['ABC', 'b', 'c', 'd']

lis = ['a','b','c','d']
lis[1:3] = 'ABC'  #将b-c这个区间的元素替换为'ABC'的每个最小元素
print(lis)  # ['a', 'A', 'B', 'C', 'd']
3.3.3 list其他常用方法

汇总一览:

注意,与字符串不同,列表的有些方法是直接对原列表进行操作的。

len() 查询列表最小元素的个数

lis = ['a','b','c',[1,'2',3]]
print(len(lis))    # 4

count()查询元素出现的次数

lis = ['a','b','c',[1,'2',3]]
a = lis.count('a')
print(a)    # 1

index()查找元素的索引值

lis = ['a','b','c',[1,'2',3]]
a = lis.index('c')
print(a)  # 2

sort()正反向大小排序

注意:该函数无返回值,直接对原列表进行操作。

# 正向排序 从小到大
lis = [1,4,7,2,3,8,6]
()
print(lis)  # [1, 2, 3, 4, 6, 7, 8]

# 倒序 从大到小
(reverse=True)
print(lis)    # [8, 7, 6, 4, 3, 2, 1]

附: 其实,sort函数还可以指定一个参数key,该函数可以改变排序。

比如: 按照绝对值的大小进行排序,那就需要将key=abs,将key赋值为内置函数abs的内存地址,可将sort函数每次迭代出来的值,先交给abs函数进行求绝对值,随后返回再进行sort排序。

l = [1,-4,6,5,-9,-2]
l.sort(key=abs)
# 输出结果: [1, -2, -4, 5, 6, -9]

reverse()列表反向排列

与sort一样,都是直接对原列表进行操作的。

lis = [1,4,7,2,3,8,6]
lis.reverse()
print(lis)  # [6, 8, 3, 2, 7, 4, 1]

copy()复制列表

注:

如果被复制的列表里面嵌套有多层,则原列表修改之后,新的列表可能会发生改变。具体请见 深浅拷贝

abc = ['1','2','4']
abc2 = ()
print(abc2)   # ['1', '2', '4']

join()列表转字符串

lis = ['接着奏乐','接着舞','dengdengdeng',['我打了一辈子','仗']]
str1 = '_'.join(lis[:3]) + '_' + '_'.join(lis[3])
print(str1)
#打印结果:接着奏乐_接着舞_dengdengdeng_我打了一辈子_仗

lis2 = ['大白菜','鸡毛菜','通心菜','油麦菜']
str2 = '*'.join(lis2)
print(str2)
#打印结果:大白菜*鸡毛菜*通心菜*油麦菜
3.3.4 列表嵌套练习

列表为:

lis = ['接着奏乐','接着舞','dengdengdeng',['我打了一辈子','仗']]

需求1:将’dengdengdeng’改为大写

lis[2] = lis[2].upper()  #或者   lis[2] = 'DENGDENGDENG'
print(lis)
#输出结果: ['接着奏乐', '接着舞', 'DENGDENGDENG', ['我打了一辈子', '仗']]

需求2:将‘仗’改为‘飞机’

lis[3][1] = lis[3][1].replace('仗','飞机')   #或者  lis[3][1] = '飞机'
print(lis)
#输出结果:['接着奏乐', '接着舞', 'dengdengdeng', ['我打了一辈子', '飞机']]

注:

字符串属于不可修改类型,变量指向的是字符串值的内存地址,我们只能修改指向,也就是重新赋值,老的值因为没有变量引用,GC机制会清理。

所以字符串的方法不能修改列表内字符串的内容,只会返回处理好的字符串。

此时我们再重新赋值即可。

3.3.5 逻辑判断相关

关键词:

in 、 not in

作用:

判断指定数据在某个列表序列,如果在返回True,否则返回False,返回的True或False后续可做if判断

代码示例:

in

abc = ['1','2','4']
print('3' in abc)    #False
print('4' in abc)	 #True

not in

abc = ['1','2','4']
print('3' not in abc) 	#True
print('4' not in abc)    #False
3.3.6 深浅copy

引子:

定义列表,并利用两种拷贝方式对列表list1进行复制

list1 = ['liuyu','22',['中国地质大学','beijing']]
list2 = list1
list3 = ()

三个列表变量在内存中的存储如下:

如图可见:

list2与list1指向的内存地址是相同的,所以当原列表list1对任何数据进行修改时,list2会跟着改变。list3重新在堆区开辟了空间用来存放每个索引对应值的内存地址。因为字符串为不可变数据类型,所以原列表对字符串进行修改时,会重新开辟空间并指向,所以影响不到list3中的字符串,因为list3始终指向的是原来拷贝过来的内存地址,而可变数据类型列表是个例外,如原列表索引2的元素(列表),因为list3指向的内存地址与list1是一样的,所以当list[2]这个内部列表的数据发生变化时,list3会受到影响,可以理解为,list1与list3指向的都是一个水瓶,里面的水换成可乐,那么都一起喝可乐。

验证:

list1 = ['liuyu','22',['中国地质大学','beijing']]
list2 = list1
list3 = ()


list1[1] = '24'
list1[2][1] = 'shanghai'


print(list1)
print(list2)
print(list3)   # 只有list3[1]元素,没有受到原列表更改的影响。

print(id(list1[0]),id(list1[1]),id(list1[2]))
print(id(list2[0]),id(list2[1]),id(list2[2]))
print(id(list3[0]),id(list3[1]),id(list3[2]))  # 打印内存地址,也证实了list3[2]与list1[2]指向的是同一个内存地址。

'''输出结果:
['liuyu', '24', ['中国地质大学', 'shanghai']]
['liuyu', '24', ['中国地质大学', 'shanghai']]
['liuyu', '22', ['中国地质大学', 'shanghai']]
2280379554864 2280382155440 2280423454464
2280379554864 2280382155440 2280423454464
2280379554864 2280379249712 2280423454464
'''

上述这种拷贝方式,统称为浅拷贝

深拷贝

import copy
list1 = ['liuyu','22',['中国地质大学','beijing']]
list4 = copy.deepcopy(list1)
print(list4)

深拷贝示意图

与浅拷贝的区别:

对于可变数据类型,重新开辟空间,与最终的值进行绑定。

因为字符串时不可变数据类型,所以即时原列表进行了数据修改,那也只是重新开辟空间存的新值而已,并没有对老的值进行什么操作,只是解绑了。 原列表解绑了,list4列表可没有,所以就不会受到任何影响了。

简单理解为,list4与list1指向的不是一个水瓶,当list1不想喝白开水,想换成芬达,那也只是把list1水瓶里面开白水掉掉,重新灌满芬达而已,不会影响list4中的白开水。

验证:

print(id(list1[0]),id(list1[1]),id(list1[2]),id(list1[2][0]),id(list1[2][1]))
print(id(list4[0]),id(list4[1]),id(list4[2]),id(list4[2][0]),id(list4[2][1]))

'''输出结果
2048401929136 2048404807024 2048446068480 2048401726576 2048404832688
2048401929136 2048404807024 2048445389376 2048401726576 2048404832688
'''

可以看到,除了不可变数据类型的列表,是重新开辟了内存空间,其他指向的内存地址都是一样的。

3.3.7 列表转字符串、集合

列表转字符串

lis = ['Cai','Xu','Kun']
str1 = ''.join(lis)
print(str1) # CaiXuKun

列表转集合

内置函数set()

lis = [1,1,2,2,3,3]
set1 = set(lis)
print(set1,type(set1))  # {1, 2, 3} <class 'set'>

3.4 元组

作用:

与列表相似,不过元组内的数据是不能修改的。(因为压根就没有提供修改元素的方法)

定义:

tup = ('张三','李四','王五')

元祖的特点:

有序,不可更改,可以有重复的元素。

可以存储多个不同数据类型的数据,每个元素之间用逗号隔开,元祖整体为小括号包裹。

但是,当元祖内的元素为可变数据类型时,如列表,那么列表中的元素可以进行更改。

tup =  ('张三','李四','王五',[1,2,3],{'name':'盖伦'})
print(tup)
# ('张三', '李四', '王五', [1, 2, 3], {'name': '盖伦'})

tup[3][0] = 0
tup[4]['name'] = '嘉文四世'
print(tup)
# ('张三', '李四', '王五', [0, 2, 3], {'name': '嘉文四世'})

元组的切片

tup = ('a','b','c','d')
# 按照索引取元素
print(tup[1])   # 输出结果:b

# 切片
print(tup[1:3])   # 输出结果:('b', 'c')
3.4.1 元组常用方法
tup =  (7,1,9,10,24,1)
res = tup.index(10)
print(res)  #输出结果: 3

res = tup.count(1)
print(res) #输出结果: 2

res = len(tup)
print(res)  #输出结果: 6
3.4.2 元组的多种定义方式

python崇尚简介,所以在上述的代码中,并没有先定义变量的数据类型,然后再赋值,本小结主要扩展下元组的其他定义方式,赋值和定义算成一步了。

# 一下多种赋值方式都是为元组。
a = 1,
b = (1,)
c = 1,2
d = (1,2)
print(type(a))	# <class 'tuple'>
print(type(b))	# <class 'tuple'>
print(type(c))	# <class 'tuple'>
print(type(d))	# <class 'tuple'>

3.5 字典

作用:

用于存放一组有对应关系的数据,如姓名与身份证号、游戏ID与游戏道具列表,等等等。

定义:

dict1 = {'name':'盖伦','age':76,'addr':'德玛西亚'}
#冒号前⾯的为键(key),简称k;冒号后⾯的为值(value),简称v。

字符串的特点:

无序(不能人为排序),可更改,有索引,没有重复的key。

{}大括号包裹,数据为键值对,每个键值对中间用逗号隔开。

键值对的格式为 key:value,其中key可以对value有描述性的功能

dict1 = {
    'name':'liuyu',
    'age':22,
    'school':'中国地质大学(北京)'
}
3.5.1 增加属性

方式一:通过赋值的方式

首先,如何获取字典字典的值?

格式:

dict[key]  # 返回为该key的value

所以当我们需要修改字典某个key的value时,可以重新赋值达到修改的效果,如:

dict1 = {'name':'liuyu','age':22,'school':'中国地质大学(北京)'}
dict1['age'] = 23
print(dict1)  
#输出结果: {'name': 'liuyu', 'age': 23, 'school': '中国地质大学(北京)'}

上述代码中,修改的是已有key的value值,当key不存在时,字典会默认创建这个key,然后赋于值。

dict2 = {'A':'a','B':'b'}
dict2['C'] = 'c'
print(dict2)
#输出结果: {'A': 'a', 'B': 'b', 'C': 'c'}

总结:

字典[key] = value 这种方法,当没有这个Key的时候会自动创建这个键值对,并添加到字典的末尾。当有key的时候则是修改value值

方式二:利用setdefault()方法增加字典的值

格式:

dict.setdefault(key,value)

特点:

当key存在不进行任何修改。当key不存在则将该键值对添加至字典的末尾。

代码示例:

dict1 = {'name':'liuyu','age':22,'school':'中国地质大学(北京)'}
dict1.setdefault('school','北京大学光华管理学院')
dict1.setdefault('addr','北京')
print(dict1)   # {'name': 'liuyu', 'age': 22, 'school': '中国地质大学(北京)', 'addr': '北京'}

可以发现,由于已经存在了,所有school的值并没有被修改,而addr属性并没有,所以就新增了。

根据具体情况来选择是方式一还是方式二。

3.5.2 删除属性或字典

方式一:pop删除指定的键值对

格式:

('要删除键值对的key','自定义报错信息')  

('要删除键值对的key',['报错1','报错2','报错3',])  

作用:

用于删除字典内指定的键值对。

特点:

该方法在删除不存在key时,会报错,但是可以返回指定的报错信息。成功删除了之后,可以返回被删除键值对的value

代码示例:

dict1 = {'name':'liuyu','age':22,'school':'中国地质大学(北京)'}
res = ('addr','未找到Key')
print(res)   #输出结果: 未找到Key

res = ('school')  #会返回key为school的value值。
print(res,dict1)  
#输出结果: 中国地质大学(北京) {'name': 'liuyu', 'age': 22}

方式二:利用popitem()方法删除最后一对属性

格式:

item()

作用:

调用该方法的字典,会删除最后一位属性,并返回被删除的键值对

代码示例:

dict1 = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190,}
print(item())  #输出结果:('身高', 190)
print(item())  #输出结果:('addr', '德玛西亚')

# 后两位已被删除
print(dict1)  #输出结果:{'name': '盖伦', 'age': 76}

删除字典方式一:利用内置方法del()删除

格式:

删除整个字典:

del 字典名

删除字典的键值对

del 字典名[key]

删除字典方式二:clear()清空字典

dict1.clear()  # 此时dict1为空字典
print(dict1) 	# 输出结果: {}
3.5.3 修改属性

方式一:直接修改

dict1 = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190}
dict1['身高'] = 150   #当添加的k已经存在,则直接修改。
print(dict1)    #身高已被修改为150
#输出结果: {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 150}

方式二:利用update方法(了解即可)

关于修改,还有另外一种方式,那就是利用update方法,将字典B同步给字典A。

将dict2字典的内容,同步到dict1中:

dict1 = {'name':'liuyu','age':'22','addr':'shanghai'}
dict2 = {'name':'xiaxia','age':'21','school':'Beijing_University'}
dict1.update(dict2)
print(dict1)
print(dict2)
#输出结果: {'name': 'xiaxia', 'age': '21', 'addr': 'shanghai', 'school': 'Beijing_University'}
#输出结果: {'name': 'xiaxia', 'age': '21', 'school': 'Beijing_University'}

可以发现,相同Key的情况下,值以dict2字典为标准,同时dict1字典中没有而dict2有的属性,会被同步过去。

当dict1中有,而dict2中没有的属性,会继续保留。

3.5.4 查找属性

如何列出字典中所有的Key、value呢。

格式:

()     # 列出字典所有的 键
dict.values()   # 列出字典所有的 值
dict.items()    # 列出字典所有的 键和值 以元组的形式展示

代码示例:

dic = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190}
print(())
#输出结果:dict_keys(['name', 'age', 'addr', '身高'])

print(dic.values())
#输出结果:dict_values(['盖伦', 76, '德玛西亚', 190])

print(dic.items())
#输出结果:dict_items([('name', '盖伦'), ('age', 76), ('addr', '德玛西亚'), ('身高', 190)])

由于python中可以多个变量赋值,所以我们可以通过循环将key键和value值,依次通过赋值打印出来(for循环等在文章后面有讲述)

dic = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190}
for k,v in dic.items():
    print(k,v)
# 因为 items() 输出的为 ('name', '盖伦'), ('age', 76), ('addr', '德玛西亚'), ('身高', 190) 
# 每个元组刚好有两个元素,这与for循环中的k和v刚好对应上,所以可以正确赋值,并打印出来。
'''输出结果:
name 盖伦
age 76
addr 德玛西亚
身高 190
'''

在之前有提到,python中字典的可以直接通过key查找value的,如:

dic = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190}
value1 = dic['name']
print(value1)  # 盖伦

但是,当中括号内的Key,在字典中并不存在时会报错,所以需要可以不报错的方法,或者可以自定义报错的方法。

get方法

格式:

('要取值的键','自定义报错信息')

代码示例:

dic = {'name':'liuyu'}
print(('name'))    # 输出结果:liuyu
print(('age','not find'))   # 输出结果:not find

字典的嵌套

现在有一个字典,名字叫做zidian,现在我们想让字符串Syria变成全大写,需要怎么操作。

zidian = {
    'name':['法外狂徒张三','李四'],
    'Learn':{
        'time':'2021/5/10,',
        'learn':'AKM的基本保养及维护,巴雷特快速换弹技术',
        'addr':'Syria'
    },
    'age':57
}

第一步,我们一层一层来拆开看看效果,先想一想字典的查是如何查的。

abc = zidian['Learn']   # 通过Key找v
print(abc) 

'''输出结果:
{
	'time': '2021/5/10,', 
	'learn': 'AKM的基本保养及维护,巴雷特快速换弹技术', 
	'addr': 'Syria'
}
'''

第二步

abc = zidian['Learn']['addr']
print(abc,type(abc))   
# 输出结果为:
# Syria   <class 'str'>  
#既然类型是str那就可以用str的方法使其变成全大写。
abc = zidian['Learn']['addr'].upper()
print(abc)   # SYRIA   这样就得到了大写的值

3.6 集合

定义:

'多个元素的无序组合,每个元素唯一,集合元素不可修改(为不可变数据类型)'

特点:

无序,无索引,没有重复的元素

集合一旦被创建,无法更改项内容,但是可以添加项

类似于高中数学中的集合,可求∩交集∪并集等。

使⽤ {} 或 set() , 但是如果要创建空集合只能使⽤ set() ,因为默认 {} 是⽤来创建空字典的。

set1 = {10, 20, 30, 40, 50}
print(type(set1)) # set
3.6.1 集合的增删改查

一、add增加数据

格式:

()

代码示例:

s1 = {10, 20}
(100)    #s1这个集合中添加100,因为集合是无序且去重的,所以这个100是随机插入的。
(10)   #因为集合是无序的且去重,所以这个10不会被添加进去。
print(s1)  # 输出结果: {100, 10, 20}

二、update 拆分元素并随机添加

格式:

set.update()

代码示例:

s1 = {10, 20}
s1.update('abc')
print(s1)   #{10, 'b', 20, 'a', 'c'}

三、删除

(1)pop随机删除

# pop随机删除,该函数会返回被删除的那个元素      
()
print(set1)   #会输出被删除的元素

(2)remove按元素删除

# remove按元素删除,该函数与pop不同,这个没有返回值  
set1.remove('1')  #如果没有这个元素会报错。
print(set1)

(3)清空与删除集合

#清空集合   clear
set1.clear()

#删除  del
del set1

四、查

由于集合并没有专门查询方法,同时也没有索引,无法知己取值,所以需要借用for循环,迭代的从数组中取值。

#通过for循环拿到集合中的每一个值
for i in set1:
    print(i)
3.6.2 求交并集

求交集的两种方式

方式一:利用关键字

set_1  = {1,5,7,9,4}
set_2 =  {6,4,2,5,9}
print(set_1 &  set_2)   # {9, 4, 5}  

方式二:利用intersection函数

print(set_1.intersection(set_2))

求并集的两种方式

方式一:利用关键字

print(set_1 | set_2)   # {1, 2, 4, 5, 6, 7, 9}
print(set_1.union(set_2))  # {1, 2, 4, 5, 6, 7, 9}

方式二:利用symmetric_difference函数

print(set_1 ^ set_2)   # {1, 2, 6, 7}
print(set_1.symmetric_difference(set_2))   # {1, 2, 6, 7}
3.6.3 利用集合实现列表去重

因为集合内的元素都是唯一的,没有重复的值,所以我们可以将列表转成集合数据类型,再转回列表。

lis = [1,1,2,2,3,3]
lis = list(set(lis))
print(lis)  # [1, 2, 3]

但是,由于集合是无序的,所以原来列表的排序,会被打乱。

3.7 补充

3.7.1 可变与不可变类型

可变类型:

值改变,id不变(内存地址),证明改的是原值,证明原值是可以被改变的.

不可变类型:

值改变,id也变了,证明是产生新的值,压根没有改变原值,证明原值是不可以被修改的

验证

int是不可变类型

x=10
print(id(x)) # 140710450899024
x=11 # 产生新值  
print(id(x)) # 140710450899056   内存地址发生的改变√

float是不可变类型

x=3.1
print(id(x)) # 2336632639536
x=3.2
print(id(x)) # 2336632639600  内存地址发生的改变√

str是不可变类型

x="abc"
print(id(x)) # 2692737058544
x='gggg'
print(id(x)) # 2692737440752  内存地址发生的改变√

小结:int、float、str都被设计成了不可分割的整体,不能够被改变。而其余的数据类型都是可更改的(元组这个只读列表除外)

列表就是可变数据类型

l=['aaa','bbb','ccc']
print(id(l))    # 2514251642368
print(id(l[0])) # 1332798747696

l[0]='AAA'
print(id(l))  #2514251642368 栈指向堆中的内存地址不变
print(id(l[0])) # 1332801653424  堆中指向的值,内存地址不一样。

经过测试,列表这种数据类型确实满足 “值改变,id不变” 这个原则,说明是可变数据类型。

3.7.2 初识编码

后续的章节中会详细介绍,具体见目录(我懒得找,哈哈哈哈,嗝~)

ASCII:字母,数字,特殊字符:都是用1个字节 8位
Unicode:2个字节16位  4个字节32位
utf-8:一个英文字母1个字节8位   欧洲两个字节16位  中文3个字节24位
gbk:英文1个字节8位  中文2个字节16位
   	
python3中默认使用的编码为:Unicode
3.7.3 bool数据类型

bool数据类型,与上述数据类型都不太一样,bool数据类型的特点就是不是True就是False,所以多用于条件判断。

flag = True
print(flag,type(flag))
#输出结果: True <class 'bool'>

3.8 格式化输出

作用:

实现将字符串中指定的内容,灵活的替换成我们想要的。

实现方式:

1.利用%s占位符来进行替换2.利用str的.format方法来进行替换3.利用 f’{}’ 这样的F语句

一、利用占位符实现格式化字符串

关键词:

%s 与 %d都是占位符,%s表示当前位置是个字符串,%d表示当前位置是个数字。

格式:

str = '%s'%(字符串)   #使用%s占了几个位置,就要补充对应多少个值,进行替换

代码示例

name = 'liuyu'
msg = '我的名字是:%s'%(name)
print(msg)
#输出结果:我的名字是:liuyu

案例:

用户输入个人信息之后,打印用户信息表

name = input('请输入姓名:')
age = input('请输入年龄:')
job = input('请输入工作:')
hobbie = input('你的爱好:')
msg = '''------------ info of %s -----------
Name  : %s
Age   : %d
job   : %s
Hobbie: %s
-------------- end ----------------''' %(name,name,int(age),job,hobbie)
print(msg)

输入信息之后,打印示例:

------------ info of liuyu ----------- Name : liuyu Age : 22 job : 后端开发 Hobbie: 吃饭 ---------------- end -----------------

本案例中注意事项:

input接收输入的信息,格式为字符串,如果站位使用的是%d是,需要注意转换数据类型。

二、利用format方法

format方法有三种使用方法,详情可见字符串常用方法

#利用位置进行替换
test1 = '每个人身上都有{},让我为你唱{}'.format('毛毛','毛毛')

#利用索引进行替换
test2 = '每个人身上都有{0},让我为你唱{1}'.format('毛毛','maomao')

#利用关键字进行替换
test3 = '你叫什么叫,{sha}'.format(sha='不服你打我')

print(test1)
print(test2)
print(test3)
# 输出内容:每个人身上都有毛毛,让我为你唱毛毛
# 输出内容:每个人身上都有毛毛,让我为你唱maomao
# 输出内容:你叫什么叫,不服你打我

三、利用F语句

格式:

f'{变量}...内容....{变量}'

代码示例:

name = '米奇'
print(f'嘿,你丫的瞅什么呢,我是你die{name}')  # F语句

# 输出内容: 嘿,你丫的瞅什么呢,我是你die米奇

另外,F语句可以执行内部代码:

f'{print("这个F真牛逼")}'  # 这个F真牛逼
f"{print('aaaa')}"  #aaaa
3.8.1 模拟进度条

本章节需要看完if判断,for循环,内置函数之后再回头查看

两种写法

# 利用覆盖输出,让每次打印的#号以及百分比数值不断变化就好。
import time
for i in range(0,101,2):
    time.sleep(0.1)
    num = i // 2
    print( '\r{}%:{}'.format(i,'#'*num) if i == 100 else '\r{}%:{}'.format(i,'#'*num),end='')   
    #不加这个end=''会自动换行,那么\r就没用了
    
#输出结果:  100%:##################################################
import time
for i in range(0,101,2):
    time.sleep(0.1)
    num = i//2
    print('\r[%-50s]%s%%'%('#'*num,i),end='')
#输出结果:[##################################################]100%

涉及到知识点详解:

开头\r 表示覆盖输出,这样不会另起一行。末尾的end= ‘’ 表示末尾不换行,因为print函数默认是end=‘\n’%s%% 两个百分号在这里可以理解为屏蔽特殊字符的意思,这样就可以输出%%50s 表示占位符的宽度是多少(50),且数字是正数表示靠右侧%-50s 表示占位符的宽度是多少(50),-50为负数表示靠左侧

四、运算符

4.1 常见的运算符

1、算数运算符

print(10 + 3.1)
print(10 + 3)
print(10 / 3)  # 结果带小数
print(10 // 3)  # 取余但只保留整数部分
print(10 % 3) # 取余数
print(10 ** 3) # 幂运算
'''输出结果:
13.1
13
3.3333333333333335
3
1
1000
'''

2、比较运算符

#2、比较运算符: >、>=、<、<=、==、!=
# 返回的结果为布尔值,条件成立则返回True,不成立返回False
print(10 > 3) # True
print(10 == 10) # True
print(10 >= 10) # True
print(10 >= 3) # True

3、逻辑运算符

#3、逻辑运算符:not、and、or
#not:将后面的条件结果取反
print(not 1>2)  #True
print(not True)  #False
print(not False)  #True

#and:用来链接左右两个条件,两个条件同时为True结果才为True。当左右两边为数字时,第一位为True则输出第二位,第一位为False时则输出第一位。(注:0表示False)
print(1+2 > 3 and 4-3<0) #False
print(0 and  3)  # 0
print(4 and  3)  # 3

#or:用来链接左右两个条件,两个条件但凡有一个为True,最终结果就为True。如果两把是数字时,当第一位为真则输出第一位,当第一位为假时则输出第二位,0表示假
print(3+7 > 5 or 9-11>0)  #True
print(6 or 7)  # 6
print(0 or 7)   # 7

# is:用来判断前者是不是后者,比较的是内存地址
str1 = 'abc'
str2 = 'abc'
print(str1 is str2)  # True

# in: 用来判断前者是否在后者里面
str = '1'
res = str in '123'
print(res)  # True

4、成员运算符

作用:

判断一个字符串,是否存在于一个字符串中

关键词:

in 是否存在not in 是否不存在

代码示例:

test = '今晚8点,锁定我的直播间,咱们嗨起来!'
print('今晚' in test)  # True

test2 = ['大锤','铁锤','头锤','榔头','二锤']
print('小锤' in test2)  #False

test3 = {'姓名':'胡图图','工资':1500,'地址':'番斗花园'}
print('爱好' in test3) #False
print(1500 in test3)   #false 因为直接对字典进行的操作大多都是对字典的Key,所以1500这个key并不存在,只有value是没用的。
print('工资' in test3)  #True

4.2 is与==

区别:

is比较的是内存地址,==比较的是值。

驻留机制:

字符串驻留,是一种在内存中,仅保存一份相同且不可变字符串的方法。

驻留适用范围

字符串长度为0或1时,默认采用驻留机制;字符串长度大于1时,且 字符串中只包含大小写字母、数字、下划线(_) 时,采用驻留机制;对于 [-5,256]之间的整数数字,Python默认驻留 ;字符串只在编译时进行驻留,而非运行时 。Python是解释型语言,但是事实上,它的解释器也可以是理解为是一种编译器,它负责将Python代码翻译成字节码,也就是.pyc文件;用乘法得到的字符串,如果结果长度 <=20且字符串只包含数字、字母大小写、下划线,支持驻留。长度>20,不支持驻留。这样的设计目的是为了保护.pcy文件不会被错误代码搞的过大。

代码示例:(需要直接打开Python解释器执行,win+r —> cmd —> python)

>>> x = 'abc:abc:abc'
>>> y = 'abc:abc:abc'
>>> print(x is y)  # 不符合驻留机制,所以不会指向同一个内存地址。
False
>>> print(x == y)
True

>>> x = 'abc_abc_abc'
>>> y = 'abc_abc_abc'
>>> print(x is y)
True
>>> print(x == y)
True
>>>

4.3 其他

逻辑运算符有优先级规则:

即 not > and > or

隐式布尔值:

所有的值都可以当成条件去用,其中0、None、空(空字符串、空列表、空字典),都代表的布尔值为False,其余都为真。

小整数池[-5,256](了解即可):

从python解释器启动那一刻开始,就会在内存中事先申请好一系列内存空间存放好常用的整数

五、 流程控制

流程控制即控制流程,具体指控制程序的执行流程,而程序的执行流程分为三种结构:顺序结构(之前章节写的代码都是顺序结构)、分支结构(用到if判断)、循环结构(用到while与for)

5.1 分支结构if

什么是分支结构:

分支结构就是根据条件判断的真假去执行不同分支对应的子代码。

分支结构的作用:

人们可以根据某些时候的条件来决定做什么事情,比如:如果今天下雨,就带伞

所以程序中必须有相应的机制来控制计算机具备人的这种判断能力。

python中if关键字可以实现分支结构,语法格式如下:

if 条件:
	条件成立执行的代码
elif 条件:
	条件成立执行的代码(可以有多个elif)
else :
	以上条件都不满足时执行的代码

条件是什么?

条件就是bool值,即True或False。如:1>2,通过运算,得到的值为False

代码示例:

# 当age这个年龄变量的值大于18时,打印已成年
age = 20
if age > 18:
    print('已成年')
# 输出结果:已成年  
# 输入分数,当分数90以上、80以上、60以上以及低于60的,输出特定信息
score = int(input('请输入本次考试得分:'))
if score >= 90:
    print('很优秀')
elif score >= 80:
    print('再接再厉')
elif score >= 60:
    print('再努努力')
else:print('你考的有点抽象啊')
5.1.1 三元运算

作用:

可以用一小段代码书写简单的if判断表达式

格式:

条件成立返回的结果 if 条件 else 条件不成立返回的结果

代码示例:

test =1 if 5>4 else 3
print(test)  #输出结果:1

test =1 if 5<4 else 3
print(test)  # 3
str1 = '1'
res = '有' if str1 in '123' else '没有'
print(res)  # 有

5.2 循环结构for

for循环

语法格式:

# 可迭代对象可以是:列表、字典、字符串、元组、集合
for 变量名 in 可迭代对象:   
	循环体
  
  变量名会每次从可迭代对象中获取值,并且执行循环体内部代码。

代码示例:

a = '嘻嘻哈哈'
for i in a :
    print(i)
    
'''输出结果:
嘻
嘻
哈
哈
''' 

变量名“i”,每次都会从变量"a"中取出一位元素,随后执行循环体内的代码。这个过程叫循环,循环的次数取决于这个变量"a"的长度。

dic = {'name': '盖伦', 'age': 76, 'addr': '德玛西亚', '身高': 190}
for k,v in dic.items():
    print(k,v)
    
'''输出结果:
name 盖伦
age 76
addr 德玛西亚
身高 190
'''   
5.2.1 continue与break

一、continue

关键字:

continue,书写位置:循环体内部

作用:

终端本次循环,进入下一次循环

代码示例:

for i in [1,2,3,4,5]:
    if i == 2 or i == 4:
        continue
    print(i)  # 输出结果: 1 3 5

当i等于2或者4的时候,结束循环,所以执行不了print

二、break

关键字:

break,书写位置:循环体内部

作用:

结束整个循环

代码示例:

for i in [1,2,3,4,5]:
    if i == 2 or i == 4:
        break
    print(i)  # 输出结果: 1 

当i等于2或者4的时候,结束整个循环,所以后续符合条件的数值都没有打印。

5.2.2 for…else语句

作用:

循环执行完之后,才会执行else里的代码。

代码示例:

当 语句中出现 break 时。

test = '123'
for i in test:
    if i == '3':
        break
    print('第%s次循环' % (i))
else:
    print('执行完毕')
    
'''输出结果
第1次循环
第2次循环
'''

当**语句中出现continue**时。

test = '123'
for i in test:
    if i == '3':
        continue
    print('第%s次循环' % (i))
else:
    print('执行完毕')

'''输出结果
第1次循环
第2次循环
执行完毕
'''

总结:

for…else语句:在循环执行完之后,才会执行else里的代码。当语句中出现 continue 时,else内的代码体仍然可以运行。当 break 时,由于退出整个循环了,那么else内的代码自然也就不执行。

5.2.3 实现99乘法表

代码:

for i in range(1, 10):
    for j in range(1, i+1):
        print(f'{j}x{i}={i*j}\t', end='')
    print()

解析:

range函数会在后面章节详细说明,range(1,4)表示可迭代3次,值为1,2,3 不包含4,顾头不顾腚,类似于切片

当i=1时,j=range(1,1+1) = 1, 所以输出1*1 = 2,\t制表符隔开,end为空表示结尾不换行,随后内部for循环执行完毕,最后执行print()换行

当i=2时,j=range(1,2+1),所以j等于1和2,所以输出 12 22

当i=3时,j=range(1,3+1),所以j=1,2,3 所以输出 13 23 3*3

…依次类推

5.3 循环结构while

语法格式:

while 条件:
	循环体
	终止循环

由于while循环的特点是,当条件成立时无限循环,所以我们不能眼睁睁得看着 死循环 发生,需要设置一些条件,然后break终止掉整个循环。

# 所以while的基础格式就成了
while 条件:
	循环体
	if 条件:
		break

代码示例:

a = 0
while a < 5:     #打印五遍
    a += 1   # a 每次循环自加一
    print('第{}遍打印'.format(a))
'''输出结果:
第1遍打印
第2遍打印
第3遍打印
第4遍打印
第5遍打印
'''

while循环中的break与continue

效果与for循环一样的

a = 0
while a < 5:
    print('while还是强啊')
    a += 1
    if a == 3:
        break
#输出结果:只打印了三次,随后整个循环就结束了

a = 0
while a < 5:
    a += 1
    if a == 2:
        continue
    else:
        print('第%s次' % (a))
#输出结果:没有第二次的,因为跳过了
5.3.1 while…else语句

当while循环执行完毕之后,再执行else里面的代码

a = 1
while a <= 3:    
    print('第{}遍打印'.format(a))
    a += 1
else:
    print('完毕')

'''输出结果:
第1遍打印
第2遍打印
第3遍打印
完毕
'''

while…else语句与break、continue

while…else语句与for…else是一样的,被break打断不会执行else内的代码。

测试如下:

当遇到break时:

a = 1
while a <= 3:
    print('第{}遍打印'.format(a))
    a += 1
    if a == 2:
        break
else:
    print('完毕')

'''输出结果:
第1遍打印
'''

当遇到continue时:

a = 1
while a <= 3:
    print('第{}遍打印'.format(a))
    a += 1
    if a == 2:
        continue
else:
    print('完毕')

'''输出结果:
第1遍打印
第2遍打印
第3遍打印
完毕
'''
5.3.2 利用while计算

计算1+2+3+4+…+100

count = 1
sum = 0
while count <= 100:
		sum = sum + count 
		count = count + 1
print(sum)
# 输出结果: 5050

求1-2+3-4+5-6 … -100的所有数的和

sum = 0
num = 1
while num <= 100:
    if num % 2 == 0:  #加奇数减偶数,所以对二取余运算。
        sum = sum - num
    else:
        sum = sum + num
    num += 1

print(sum)
# 输出结果: -50
5.3.3 与for的异同

相同之处:

都是循环,for循环可以干的事,while循环也可以干

不同之处:

while循环称之为条件循环,循环次数取决于条件何时变为假或者break。for循环称之为"取值循环",循环次数取决in后包含的值的个数。

六、字符编码

python解释器执行文件的流程:

启动pyhon解释器,也就是解释器将硬盘上的 .py 文件读取到内存中解释器解释刚刚读入内存的内容,开始识别Python语法

什么是字符串编码:

人类在与计算机交互时,用的都是人类能读懂的字符,如中文字符、英文字符、日文字符等,而计算机只能识别二进制数。

所以由人类的字符到计算机中的数字,必须经历一个翻译的过程,而过程必须参照一个特定的标准,该标准称之为字符编码表,该表上存放的就是字符与数字一一对应的关系,类似于中英文对照表,你好=hello

ASCII码

计算机起源于美国,所以最先考虑仅仅是让计算机识别英文字符,于是诞生了ASCII表

ASCII表的特点

只有英文字符与数字的一一对应关系一个英文字符对应1Bytes,1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符

此时:

只能识别英文字符,其他国家的字符并不支持。

文件读取或存储到内存、硬盘,参照的都是ASCII编码

此时文件是以ASCII码的二进制存储在硬盘上,当需要读取时,会从硬盘里取出读入到内存中,并且也是ASCII码的二进制,随后文本编辑器再对ASCII进行解码,解码的编码要和文件本身的一致。

GBK编码

为了让计算机能够识别中文和英文,中国人定制了GBK

GBK表的特点

只有中文字符、英文字符与数字的一一对应关系一个英文字符对应1Bytes,一个中文字符对应2Bytes 1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符2Bytes=16bit,16bit最多包含65536个数字,可以对应65536个字符,足够表示所有中文字符

每个国家都有各自的字符,为让计算机能够识别自己国家的字符外加英文字符,各个国家都制定了自己的字符编码表,就造成了…

存入内存 存入硬盘 存入内存 存入硬盘 存入内存 存入硬盘 英文字符 ASCII码二进制 ASCII码二进制 中文字符 GBK码二进制 GBK码二进制 日文字符 Shift_JIS码二进制 Shift_JIS码二进制

这种场面下,为了让软件读取到内存时不乱吗,内存中就需要出现一种编码,一种可以兼容万国的编码,不管存入到硬盘的是什么编码,在存入内存时都转成万国码,支持所有字符,这个码就是unicode编码

unicode编码

特点:

存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符。与传统的字符编码的二进制数都有对应关系。

有了unicode编码之后,文本编辑器输入字符的流程就变成了…

存入内存 存入硬盘 存入内存 存入硬盘 存入内存 存入硬盘 英文字符 unicode编码的二进制 ASCII编码的二进制 中文字符 unicode编码的二进制 GBK编码的二进制 日文字符 unicode编码的二进制 shift_JIS编码的二进制

编码与解码

由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode

由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode

uft-8的由来

如果文件保存到硬盘的是GBK格式二进制,那么用户打开之后,重新编辑输入的字符只能是中文或英文,那如果我们输入的字符中包含多国字符,要如何处理?

	理论上,是可以将内存中unicode格式的二进制,直接存放于硬盘中的,毕竟是万国符嘛。

	但是,由于unicode固定使用两个字节来存储一个字符,如果包含大量的英文字符时,使用unicode格式存放会额外占用一倍空间(英文字符其实只需要用一个字节存放即可),并且当我们由内存写入硬盘时会额外耗费一倍的时间,所以将内存中的unicode二进制写入硬盘或者基于网络传输时必须将其转换成一种精简的格式,这种格式即utf-8(全称Unicode Transformation Format,即unicode的转换格式)

存入内存 存入硬盘 多国字符 unicode编码的二进制 utf-8编码的二进制

那为何在内存中不直接使用utf-8呢?

utf-8是不定长的:一个英文字符占1Bytes,一个中文字符占3Bytes,生僻字用更多的Bytes存储,

所以这里面势必要进行一些计算,内存中使用unicode编码这种固定2字节的,会更节省时间。

6.1 字符编码的应用

了解字符编码就是为了存取字符时不发生乱码问题:

内存中固定使用unicode无论输入任何字符都不会发生乱码我们能够修改的是存/取硬盘所使用的编码方式,如果编码设置不正确将会出现乱码问题。乱码问题分为两种:存乱了,读乱了。 存乱了:如果用户输入的内容中包含中文和日文字符,如果单纯以shift_JIS存,日文可以正常写入硬盘,而由于中文字符在shift_jis中没有找到对应关系而导致存乱了读乱了:如果硬盘中的数据是shift_JIS格式存储的,采GBK格式读入内存就读乱了

python解释器执行文件

python解释器读文件时,采用的编码方式为文件当初指定的编码格式,如果没有设置,python解释器则才用默认的编码方式,在python3中默认为utf-8,在python2中默认为ASCII

在文件首行写入包含'#'号在内的以下内容
# coding: 当初文件写入硬盘时采用的编码格式

一个文件,编码格式为GBK,存入硬盘为utf-8的二进制,当使用python解释器打开时,现将硬盘里的utf-8二进制,转换成Unicode的二进制,随后python读取,如果没有指定编码为GBK,那么默认的utf-8格式和GBK 由于不是同一种编码,所以会乱码。

存入硬盘 读取存入内存 GB2312编码的文件 utf-8编码的二进制 Unicode编码的二进制 python解释器

乱码,因为pycharm默认编码为utf-8,不是GBK(GB2312)

字符串encode编码与decode解码的使用

# 1、unicode格式------编码encode-------->其它编码格式
>>> x='上' # 在python3在'上'被存成unicode,因为变量的值是存入到内存的
>>> res=x.encode('utf-8')
>>> res,type(res) # unicode编码成了utf-8格式,而编码的结果为bytes类型,可以当作直接当作二进制去使用
(b'\xe4\xb8\x8a', <class 'bytes'>)

# 2、其它编码格式------解码decode-------->unicode格式
>>> res.decode('utf-8') 
'上'

七、文件操作

引子:

应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须要保存于硬盘中。应用程序若想操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程。

利用python打开文件

利用python打开文件,需要知道:

文件路径编码方式操作方式(只读,只写,只追加,读写)

格式:

open('文件路径',mode='操作方式',encoding='编码方式') 
#mode可以省略不写,利用位置传参,直接写操作方式,如"r+",

open函数返回一个文件对象,该对象有 read 方法,可以返回 文件句柄,文件句柄后续对内容等操作都需要使用。文件句柄还有一个 close 方法,关闭文件请求,回收系统资源。

注意:

encoding参数如果不赋值的话,那么将按照系统为准,window为GBK,linux为utf-8,注意是系统,不是解释器。mode可以省略不写,直接写操作方式,如"r+"

代码示例:

# 路径中个别地方需要用反斜来转义,如D:\\新建文本文档.txt
file = open('D:\新建文本文档.txt',encoding='utf-8')   # 接收open函数返回的文本IO对象

data = ()  #调用读方法,随后会被操作系统转换为读硬盘操作
# 此时data为文件句柄,后续对文件内容的操作都需要通过它。

print(data)  # 打印文件内容

file.close() # 向操作系统发起关闭文件的请求,回收系统资源

7.1 资源回收与with上下文管理

打开一个文件包含两部分资源:

应用程序的变量file

操作系统打开的文件

所以,在操作完毕一个文件时,必须把与该文件的这两部分资源全部回收,回收方法为:

file.close()  #回收操作系统打开的文件资源
del file  #回收应用程序级的变量

其中del file一定要发生在file.close()之后,否则就会导致操作系统打开的文件无法关闭,白白占用资源, 虽然python自动的 垃圾回收机制 决定了我们无需考虑del file,但在操作完毕文件后,最好还是记住file.close()

with open() as

既然del file这个操作由垃圾回收机制帮我们做了,那单独一个close()就更容易被遗忘了,所以python提供了 with关键字 来帮我们管理上下文。

格式:

with open('文件路径','操作方式') as 别名:
    子代码块

在执行完子代码块后,with 会自动执行f.close()

#可用with同时打开多个文件,用逗号分隔开即可
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:  
    data = ()
    write_f.write(data)  #将a.txt文件中的内容,写入到b,txt

7.2 文件的操作模式

w 表示只写w+表示可写可读wb以bytes类型读取,主要针对于非文字类的a 表示只追加a+可读可追加t 模式只能用于操作文本文件

7.2.1 读

相关方法:

read() :读取所有内容,执行完该操作后,文件指针会移动到文件末尾,同一时间所有内容都被提取出来,并占用了空间。

readline():读取一行内容,光标移动到第二行首部。

readlines():读取每一行内容,存放于列表中,同一时间所有内容都被提取出来,并占用了空间。

也可以配合for循环使用,同一时刻只读入一行内容到内存中。

注:在使用read和readlines的时候,要考虑到文件的大小。

代码示例:

readline

with open('','r',encoding='utf-8') as f:
    print(f.readline())
    print(f.readline())
    print(f.readline())
    
'''输出结果:
2021年5月10日

2021年5月16日

2021年5月19日
'''
readline把文件内每一行末尾换行也读出来了,所以这里会有很大的“空隙”,其实是“\n”换行。

read

with open('','r',encoding='utf-8') as f:
    print(f.read())
    
'''输出结果:
2021年5月10日
2021年5月16日
2021年5月19日
'''    

readlines

with open('','r',encoding='utf-8') as f:
    print(f.readlines())
    
'''输出结果:
['2021年5月10日\n', '2021年5月16日\n', '2021年5月19日']
''' 

for循环

with open('','r',encoding='utf-8') as f:
    for i in f:
        print(i)
        
'''输出结果:
2021年5月10日

2021年5月16日

2021年5月19日
'''

只读 r 和 rb

只读:

文件名:
	- D:\\
文件的内容:
	- 	2021年5月16日
	-	2021年5月16日
file = open('D:\\',encoding='utf-8')
data = lines()
for i in data:
    print(i)
file.close()
# 输出结果: 2021年5月16日
#          2021年5月16日

流程如下:

文件是什么编码格式,最终从内存里获取到的,也要用相同的方式解码,否则就会乱码 存储在硬盘里 读取到内存中 指定解码为utf-8 文件编码为UTF-8 utf-8编码的二进制 unicode的二进制bytes数据类型

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值