python基础语法全解(两万字讲解,建议收藏)
文章目录
1.常量和表达式
我们可以把Python当成一个计算器,来进行一些算术运算。
print(1+2+3)
print(2*9)
print(9/2)
#打印结果
#6
#18
#4.5
print
是python的一个内置函数,功能就是打印到显示器中。
值得注意的是,在python中直接
/
结果是会保留一位整数的,这点和C/C++以及Java是不同的。不过你想要取整的化可以使用2 // 3
来执行。
2.变量与类型
在C/C++中,当我们要进行计算时,通过需要把一些计算的中间过程保存起来,这个时候需要使用到变量了。
a = 1
b = 2
c = a+b
print(c)
#打印结果:3
这里的a,b,c
就是变量。
变量可以视为一块能够容纳数据的空间,这个空间往往对应到内存这样的硬件上。
2.1 变量的语法
2.1.1 定义变量
a = 100
# a为变量名 = 为赋值运算符 100为变量的赋值
通过定义变量,如果你学过C/C++或者Java你会发现。这里没有确定变量的类型,其实在python中中是不需要确定变量的类型,其类型会根据你的赋值,自动定义。
2.1.2 变量命名规则
totalCount
,除了首个单词外,其余单词首字母大写。2.1.3 使用变量
读取变量的值
a = 10
print(a)
修改变量的值
a = 10
a = 20
print(a)
值得注意的是,因为python当成定义不需要确定类型的缘故,修改变量的值和定义变量的时看起来是没有区别的
赋值给其他变量
a = 10
b = a
print(a)
print(b)
3. 变量的类型
变量里面存储的不仅仅是数字,还可以存储其他种类的数据,我们引入了类型这样的概念。
上文也说了,python和C/C++/Java是不同的,不需要显式指定,而是在赋值的时候确定的。
那么如何知道python中的类型呢?
python提供了type
这个内置函数。
a = 10#整型
b = 1.1#浮点型
c = "abc"#字符串
d = True#布尔类型
print(type(a))
print(type(b))
print(type(c))
print(type(d))
"""
打印结果
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>
"""
3.1 整型
和C++/java等语言不同,python的int类型变量,表示的数据范围是没有上限的,只要内存足够,理论上是可以无限大的。
3.2 浮点型
与C++/java等语言不同,python的小数只有float一种类型,没有double类型,但实际上python中的float就相当于C++/java中的double,表示双精度浮点数。
3.3 字符串
在python中使用''
或者""
都可以表示字符串。
可以利用内置函数len
来测量字符串的长度。
a = 'abcdef'
print(len(a))
# 打印结果: 6
可以使用+
来对两个字符串进行连接。
a = 'hello '
b = 'yui'
print(a+b)
#打印结果:hello yui
注意不要用不同类型的变量进行相加。
3.4 布尔类型
True 表示真
False 表示假
用于逻辑判断。
3.5 为什么需要多种类型
- 类型决定了数据在内存中占据的多大空间。
- 类型其实也确立你能对这个变量进行怎么的操作。
3.6 动态类型
在python中,一个变量是什么类型,是可以在程序运行过程中改变的,这个特性称为动态类型
a = 10
print(type(a))
a = "hahaha"
print(type(a))
'''
<class 'int'>
<class 'str'>
'''
在程序运行过程中a的类型由int变成了str
C++/java这种语言是不允许这样的操作的,一个变量定义类型后就固定了。这样的特性就被称为静态类型。
动态类型,尽管会大大节约代码量,但是对于非本代码的创造者来说是会增加阅读难度的。
4.注释
在前面的代码中我已经在运用注释了,那么注释是什么呢?
注释是一种对代码的解释,能够帮助程序员能好的理解代码,同时不会影响程序的运行。
在初期的代码量极少的情况下,注释的作用可能可有可无,但是一旦开始写一些复杂的程序时,注释的作用就非常的大了,如果某段代码你长时间没有接触后在次接触时,注释会为你节约大量的理解时间,对于他人同样如此。
4.1 注释语法
4.1.1 注释行
使用#
开始的行都是注释。
#注释
4.1.2 文档字符串
使用三引号引起来的称为文档字符串
,也可以将其视为一种注释。
'''
或者"""
都可。'''
文档字符串
文档字符串
文档字符串
'''
4.1.3 注释的规范
- 内容准确:注释内容要和代码一致,匹配,并在代码修改时及时更新。
- 篇幅合理:注释不应该太精简,同时也不能篇幅太长。
5.输入输出
为了和用户进行交互。
输入和输出最基本的方法就是控制台,用户提供控制台输入一些字符串,程序在通过控制台打印一些字符串。
5.1 通过控制台输出
使用内置函数print
输出到控制台
print('hello!!!!!!!!')
输出num = 100
num = 100
print(f'num = {num}')
#打印结果:num = 100
f-string
。5.2 通过控制台输入
python使用input函数来读取用户的输入。
num = 0
num = input('请输入一个整数:')
print(f'你输入的整数是:{num}')
'''
请输入一个整数:1000
你输入的整数是:1000
'''
a = input('请输入第一个整数:')
b = input('请输入第二个整数:')
print(f'a + b = {a+b}')
'''
请输入第一个整数:12
请输入第二个整数:34
a + b = 1234
'''
这里的+
是字符串拼接。
为了避免这种情况,我们需要进行类型转化。
a = int(input('请输入第一个整数:'))
b = int(input('请输入第二个整数:'))
print(f'a + b = {a+b}')
'''
请输入第一个整数:12
请输入第二个整数:34
a + b = 46
'''
6.运算符
6.1 算术运算符
像+ - * / % ** //
这些进行算术运算的运算符都是算术运算符。
整数/整数
结果可能是小数,而不会截断。%
是求余数的意思。**
是求乘方,不光能算整数次方,而可以计算小数次方。//
是取整除法,当结果为小数时,会像下取整。6.2 关系运算符
像< <= > >= == !=
这一系列的运算符被称为关系运算符,它们是在比较操作数间的关系。
<=
小于等于>=
大于等于==
等于!=
不等于一旦关系表达式符合,那么表达式会返回True,如果不符合,表达式会返回False
a = 100
b = 10
print(a == b)
print(a != b)
print(a > b)
print(a >= b)
print(a > b)
print(a <= b)
'''
False
True
True
True
True
False
'''
除此之外,python还可以进行字符串的比较。
a = 'hello'
b = 'world'
print(a == b)
print(a != b)
print(a > b)
print(a >= b)
print(a > b)
print(a <= b)
'''
False
True
False
False
False
True
'''
对于浮点数来说,不能使用 == 判定相等。
print(0.1+0.2 == 0.3)
# False
print(0.1+0.2)
#0.30000000000000004
浮点数在计算机中的表示并不是精确的,在计算过程中,容易出现非常小的误差。
为此我们只能自己限定一个误差范围来进行比较。
a = 0.1+0.2
b = 0.3
print(-0.000001<(a-b)<0.000001)
6.3 逻辑运算符
像ans or not
这一系列的运算符称为逻辑运算符。
a = 10
b = 20
c = 30
print(a < b and b < c)
print(a < b and b > c)
print(a > b or b > c)
print(a < b or b > c)
print(not a < b)
print(not a > b)
'''
True
False
False
True
False
True
'''
在python中a<b and b<c
可以写成a<b<c
这个设定和大部分编程语言都不一样。
关于短路问题
6.4 赋值运算符
对于=
的使用
=
是表达赋值的意思,要和==
区分
链式赋值
a = b = c = 100
多元赋值
a,b = 10,100
利用多元赋值实现两个变量的交换。
# 常规写法
a = 10
b = 20
tmp = 10
a = b
b = tmp
#多元赋值
a = 10
b = 20
a,b = b,a
复合赋值运算符
python还有一些复合赋值运算符,比如:+= -= *= /= %=
# a += 1 等同于 a = a+1
a = 10
a = a + 1
print(a)
a = 10
a += 1
print(a)
#11
#11
注意:python中不支持++ --
这种自增/自减运算符。
7.顺序语句
默认情况下,python的代码都是按照从上到下的顺序依次执行的。
print('hello ')
print('world')
结果一定是hello world。写代码是一件有条理的事情,只有安排好任务的顺序,计算机才可以准确的执行任务。
8.条件语句
条件语句能够表达,如果…那么的意思。这构成了计算机中的逻辑判断。
条件语句也可以叫做分支/选择语句,因为它真的将程序的执行分成了多条路。
![[Pasted image 20240629135602.png]]
在生活中经常有人说如果怎么这么样,就会怎么这么样。这就是一个选择语句,如果满足这个条件就会进入相应的事件。就像galgame当中选择合适的选项就可以进入相应人物的故事线,将其攻略。这就是选择!
8.1 语法格式
if语句
if expression:
do_something1
do_something2
next_something
只有当expression为True时才会执行do_something1 do_something2和next_something。
否则只会执行next_something。
if else
if expression:
do_something1
else:
do_something2
当expression为True时,执行do_something1
否则执行do_something2
if elif else
if expression1:
do_something1
elif expression2:
do_something2
else:
do_something3
如果expression1为True,执行do_something1。
如果expression1为False,且expression2为True,执行do_something2。
如果expression1为Flase,且expression3为False,执行do_something3。
注意:如果你已经学过其他的编程语言,可能会觉得python和大多数的语言不太一样。
:
作为结尾。{}
#学习python的态度
choice = input("输入 1 表达好好学习python,输入 2 表达躺平摆烂\n")
if choice == '1':
print('成为python领域高手')
elif choice == '2':
print('成为躺平领域高手')
else :
print('输入错误')
9.缩进与代码块
代码块指的是一组放在一起执行的代码。
子啊python使用缩进来表示代码块,不同级别的缩进,程序的执行效果是不同的。
写一个多层的if语句嵌套来感受一下。
if a == 1:
if b == 2:
if c == 3:
if d == 4:
if e == 5:
print('haha')
print('d == 4')
print('c == 3')
大家觉得怎么样呢?至此江湖上便流传了写python需要自备游标卡尺的传说。
一些小练习:
- 输入一个整数,判断是否是奇数。
- 输入一个整数判断是正数还是负数。
- 判断年份是否是闰年。
#1
num = int(input('输入一个整数:'))
if num%2 == 0:
print('num是偶数')
else:
print('num是奇数')
#2
num = int(input('输入一个整数:'))
if num>0:
print('num是正数')
elif num<0:
print('num是负数')
else:
print('num是0')
#3
year = int(input('请输入一个公元年份:'))
if (year%4 == 0 and year%100 != 0) or year%400 == 0:
print('year是闰年')
else:
print('year是平')
10.空语句 pass
a = int(input('输入一个整数:'))
if a == 1:
print('hello')
#等价于
a = int(input('输入一个整数:'))
if a != 1:
pass
else:
print('hello')
pass就是一个空语句,就相等于C语言里的;
。
11.循环语句
有些操作需要反复执行的,这种就需要使用到循环语句。
11.1 while循环
语法格式:
while expression:
do_something#循环体
#打印1~10的整数
num = 1
while num<=10:
print(num)
num+=1
#计算1+2+3+...+100
num = 1
sum_ = 0
while num<=100:
sum_+=num
num+=1
print(sum_)
#奇数10的阶乘
num = 1
sou = 1
while num<=10:
sou*=num
num+=1
print(sou)
11.2 for循环
基本语法
for 循环变量 in 可迭代对象:
循环体
注意:
还是直接看代码,更容易理解。
#打印1~10
for i in range(1,11):
print(i)
#打印1~10间的偶数
for i in range(2,11,2):
print(i)
#打印10~1
for i in range(10,0,-1):
print(i)
#计算1+2+3+...+100
sum_ = 0
for i in range(1,101,1):
sum_+=1
print(sum_)
使用range函数,能生成一个可迭代对象,生成范围为,
[)
是一个左闭右开的范围,同时range还右第3个参数,可以指定步长,不写的化默认是1。
11.3 continue与break
continue表示结束本次循环,进入下一次的循环。
for i in range(1,10):
if i == 5:
continue
print(i)
'''
1
2
3
4
6
7
8
9
'''
可以发现没有5,5被跳过去了。这就是continue的功能。
break表示结束整个循环。
for i in range(1,10):
if i == 5:
break
print(i)
'''
1
2
3
4
'''
可以发现4后面就没有结果了,那是因为循环在5时就已经退出了。
12.函数
无论是编程中的函数还是数学中的函数,本质都是差不多的,丢给函数一些值,函数在经过一系列的处理返回一个值。不过编程上函数也可以不返回值就是了。
可以把编程上的函数理解为一段可以重复使用的代码片段.
求一段区间的和。
#求1~100的和
sum = 0
for i in range(1,101):
sum+=1
print(sum)
#求1~1000的和
sum = 0
for i in range(1,1001):
sum+=i
print(sum)
#求20~40的和
sum = 0
for i in range(20,41):
sum+=i
print(sum)
这3段代码都同质化严重,就只有for循环之中的范围变了,那么我们就可以把其写为一个函数来多次调用。
#定义函数
def calcSum(left,right):
sum = 0
for i in range(left,right):
sum+=i
print(sum)
#调用函数
calcSum(1,101)
calcSum(1,1001)
calcSum(20,41)
'''
5050
500500
630
'''
是不是很简洁,这就是函数的运用,把重复的代码给消除了。
12.1 语法格式
创建函数/定义函数
def 函数名(形参列表):
函数体
return 返回值
调用函数/使用函数
函数名(实参列表)#不考虑返回值
返回值 = 函数名(实参列表)#考虑返回值
函数只有在被调用时才会执行。
函数必须先定义再使用。
test()
def test():
print('hahaha')
此时会报错,因为还没有定义就执行了。
12.2 函数参数
在函数定义的时候,可以在()中指定形式参数
简称形参,然后在调用时,由调用者把实际参数
简称实参,传递过去。
这样就可以做到一份函数,针对不同的数据进行计算处理。
#定义函数
def calcSum(left,right):
sum = 0
for i in range(left,right):
sum+=i
print(sum)
#调用函数
calcSum(1,101)
calcSum(1,1001)
calcSum(20,41)
在这个代码中,left right
就是函数的形参,1,100...
就是函数的实参。
注意:
def test(tmp):
print(tmp)
test(10)
test('hahaha')
test(False)
'''
10
hahaha
False
'''
12.3 函数的返回值
函数的参数可以视为函数的输入,那么函数的返回值就可以视为函数的输出。
为了方便理解,我们可以把函数想象成一个工厂,所谓的函数输入就是提供给工厂的原材料,函数输出就工厂提供的产品。
还是上面的求和函数
##无返回值
#定义函数
def calcSum(left,right):
sum = 0
for i in range(left,right):
sum+=i
print(sum)
#调用函数
calcSum(1,101)
##有返回值
def calcSum(left,right):
sum = 0
for i in range(left,right):
sum+=i
return sum
#调用函数
print(calcSum(1,101))
这两种代码的区别就在于,前者直接子啊函数的内部就打印了,后者使用了return语句把结果返回給函数的调用者,再有调用者负责打印。
为了满足
逻辑和用户交互分离
的编程原则,第二种写法更好。在第一种写法中,然后后续我们需要保存结果到文件中,或者通过网络发送,第一种写法就难以胜任了。而第二种写法只负责计算逻辑不负责和用户交互,那么就会有更多的搭配可以实现。
一个函数可以有多个return
语句。
#判断一个整数是否为奇数
def isOdd(num):
if num%2 == 0:
return False
else:
return True
x = int(input("输入一个整数:"))
ret = isOdd(x)
print(ret)
执行到return
语句函数便会退出,回到开始调用的位置。
验证:
#判断一个整数是否为奇数
def isOdd(num):
if num%2 == 0:
return False
return True
ret = isOdd(10)
print(ret)
num是偶数,返回Flase后不会再返回True了。
python可以同时返回多个值,使用,
来分割多个返回值。
def test():
a = 100
b = 200
return a,b
x,y = test()
print(x)
print(y)
'''
100
200
'''
如果需要关注其中的部分返回值,可以使用_
来忽略不需要的返回值。
def test():
a = 100
b = 200
return a,b
_,y = test()
print(y)
# 200
12.4 变量作用域
def test():
a = 100
b = 200
return a,b
a,b = test()
观察代码,函数内外部存在相同命名的变量。但其实这两组变量是不同的变量,只是名字相同,它们的地址是不会相同的。
每个变量都有它们的作用域,变量只能在自己的作用域中生效。
def test():
a = 100
b = 200
return a
print(a)
# error name 'a' is not defined
在不同的作用域中,允许存在不同同名的变量。
x = 10
def test():
x = 100
print(f'函数内部x = {x}')
test()
print(f'函数外部x = {x}')
'''
函数内部x = 100
函数外部x = 10
'''
如果函数内部尝试访问的变量在局部不存在就会尝试去全局去寻找。
x = 100
def test():
print(f'x = {x}')
test()
# 100
如果想要在函数内部修改全局变量的值,需要使用global关键字声明。
x = 100
def test():
global x
x = 10
print(f'函数内部x = {x}')
test()
print(f'函数外部x = {x}')
'''
函数内部x = 10
函数外部x = 10
'''
如果没有global的声明的话,系统会认为x = 10是一个新创建的局部变量。
if/while/for等语句不会影响到变量作用域,也就是说,在if/while/for中定义的变量,在语句外也可以正常使用。
for i in range(1,10):
print(f'函数内部 i = {i}')
print(f'函数外部 i = {i}')
12.5 函数的执行过程
def test():
print('hahaha')
print('hahaha')
print('xixixi')
test()
print('xixixi')
12.6 链式调用
其实前面我们已经用过链式调用了
##有返回值
def calcSum(left,right):
sum = 0
for i in range(left,right):
sum+=i
return sum
#调用函数
print(calcSum(1,101))#链式调用
把一个函数的返回值,作为另一个函数的参数就是链式调用。
12.7 嵌套调用
函数内部还可以调用其他的函数,这叫做嵌套调用。
def testPrint():
print('嵌套调用')
print('嵌套调用')
print('嵌套调用')
test函数内调用了print函数
一个函数里面可以嵌套调用任意多个函数。
函数嵌套的过程是非常灵活的。
def a():
print('a')
def b():
a()
print('b')
def c():
b()
print('c')
c()
'''
a
b
c
'''
12.8 函数栈帧
函数之间的调用关系,在python中会使用一个特定的数据结构来表示,称为函数调用栈。每次的函数调用,都会在调用栈里新增一个元素,称为栈帧。
每个函数的局部变量都包含在自己的栈帧中。
12.9 函数递归
递归是嵌套调用中的一种特殊情况,就是自己调用自己。
程序调用自身的编程技巧称为递归(recursion)
递归作为一种算法在程序设计语言中广泛应用.一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型问题层层转化为一个于原问题相似的规模较小的问题来求解.
递归策略
只需要少量的代码就可以描述出解题所需要的多重计算,大大的减少程序的代码量.
递归的主要思想在于:把大事化小
#计算10的阶乘
def factor(n):
if n == 1:
return 1
return n*factor(n-1)
print(factor(10))
## 3628800
注意:递归代码要保证
递归的优点:
数学归纳法
明确初始条件,盒递推公式,就可以解决一系列的问题。递归的缺点:
12.10 参数默认值
Python中的函数,可以给形参指定默认值。
带有默认值的参数,可以子啊调用的时候不传参。即缺省参数
def add(x,y,debug = False):
if debug:
print("haha")
return x+y
print(add(1,2))
print(add(10,20,True))
'''
3
haha
30
'''
注意:带有默认值的参数需要放到没有默认值得参数后面
12.11 关键词参数
在调用函数得时候,需要给函数指定实参,一般默认情况下是按照形参得顺序,来传递实参的。但是我们也可以通过关键字参数,来调整这里的传参顺序,显式指定当前实参传递给哪个形参。
def test(x,y):
print(f'x = {x}')
print(f'y = {y}')
test(x = 10,y = 20)
test(y = 111,x = 222)
'''
x = 10
y = 20
x = 222
y = 111
'''
13.列表与元组
在编程中,经常需要使用变量来保存数据,如果数据比较少,我们创建几个变量也就算了,那如果数据很多呢。
a = 1
b = 2
c = 3
...
甚至有些时候数据多到你都不清楚到底有多少,那么就需要使用到列表了。
列表是一种让程序员再代码中批量表示/保存数据的方式。
那什么是元组呢?
元组和列表相比,非常类似。区别再于列表中放哪些元素可以修改调整,元组中放的元素是创建元组时就设定好的,不能修改调整。
这点也就说明列表是动态的而元组是静态的。其实也就相当于C语言的数组,一个是动态数组,一个是动态数组。
13.1 创建列表
[]
表示一个空列表。alist = [] #1
alist = list()#2
print(type(alist))
#<class 'list'>
[]
中就可以了。可以直接使用print来打印list中的元素。
alist = [1,2,3,4,5]
print(alist)
# [1, 2, 3, 4, 5]
alist = [1,'hahhaaa',1.0]
print(alist)
#[1, 'hahhaaa', 1.0]
13.2 下标访问
[]
来获取列表中的任意元素。这点就和C语言类似了,通过在
[]
填写下标索引来访问元素。alist = [1,2,3,4,5]
print(alist[0])
# 1
注意:下标是从0开始的,后续依次递增。
同样我们不仅可以通过下标访问列表元素,还可以通过下标来修改元素。
alist = [1,2,3,4,5]
alist[0] = 100
print(alist[0])
# 100
注意:下标访问时,一定不要超出列表的有效范围,否则会抛出异常,报错的。
alist = [1,2,3,4,5]
print(alist[10])
# IndexError: list index out of range
因为下标是从0开始的,因此下标的有效范围[0,列表长度-1]
,可以使用len函数来获取列表的长度。
alist = [1,2,3,4]
print(len(alist))
# 4
特别的是在python中,下标是可以取负值的,表示倒数第几个元素。
alist[-1] = alist[len(alist)-1]
13.3 切片操作
如果说通过下标操作是一次获取一个数,那么切片操作就是一次获取一个子列表。
语法:
使用[:]来进行切片
alist = [1,2,3,4,5]
print(alist[1:3])
#[2, 3]
alist[1:3]中的1:3使用的是左闭右开的区间,也就是[1,3)
关于切片的特殊操作
- 省略边界
alist = [1,2,3,4,5]
print(alist[1:]) #省略后边界,表示获取到列表的末尾
print(alist[:-1]) #省略前边界,表示从列表开头开始获取
print(alist[:]) #省略两个边界,表示获取整个列表
'''
[2, 3, 4, 5]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
'''
- 指定步长
alist = [1,2,3,4,5,6,7,8,9,0]
print(alist[::1])
print(alist[::2])
print(alist[::3])
print(alist[::4])
'''
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
[1, 3, 5, 7, 9]
[1, 4, 7, 0]
[1, 5, 9]
'''
如果指定的步长为负值,则会从后往前遍历。
alist = [1,2,3,4,5,6,7,8,9,0]
print(alist[::-1])
print(alist[::-2])
print(alist[::-3])
print(alist[::-4])
'''
[0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[0, 8, 6, 4, 2]
[0, 7, 4, 1]
[0, 6, 2]
'''
注意:在切片中填写的数字越界了,不会有负面效果,编译器只会尽可能地把满足条件地元素显示。
13.4 遍历列表元素
‘遍历’指的是把元素一个一个的取出来,再分别进行处理。
alist = [1,2,3,4,5]
for elem in alist:
print(elem)
alist = [1,2,3,4,5]
for i in range(0,len(alist)):
print(alist[i])
如果是while循环的话。
alist = [1,2,3,4,5]
while i < len(alist):
print(alist[i])
i+=1
13.5 新增元素
使用append
方法/函数,向列表末尾插入一个元素。
alist = [1,2,3,4,5]
alist.append('elem')
print(alist)
# [1, 2, 3, 4, 5, 'elem']
使用insert
方法/函数,向任意位置插入一个元素。
alist = [1,2,3,4,5]
alist.insert(1,'elem') #第一次参数就是要插入的下标位置。
print(alist)
# [1, 'elem', 2, 3, 4, 5]
13.6 查找元素
in
操作符,判断元素是否在列表中存在,返回值是布尔类型。alist = [1,2,3,4]
print(2 in alist)
print(100 in alist)
'''
True
False
'''
index
方法,查找元素再列表中的下标,返回值是一个整数,如果元素不存在会报错。alist = [1,2,3,4,5]
print(alist.index(2))
print(alist.index(10))
'''
1
ValueError: 10 is not in list
'''
13.7 删除元素
使用pop
方法删除末尾元素,即尾删。
alist = [1,2,3,4,5]
alist.pop()
print(alist)
'''
[1, 2, 3, 4]
'''
同时pop
也能根据所提供的下标进行定点删除。
alist = [1,2,3,4,5]
alist.pop(2)
print(alist)
# [1, 2, 4, 5]
如果不知道下标,列表还提供了remove
方法,进行删除对应元素的操作
alist = [1,2,3,4,5,5,5]
alist.remove(5)
print(alist)
#[1, 2, 3, 4, 5, 5]
不过只会删除一个元素。
13.8 连接列表
使用+
可以使连个列表连接起来
alist = [1,2,3]
blist = [4,5,6,7]
print(alist+blist)
# [1, 2, 3, 4, 5, 6, 7]
此处的+
是会生成一个新的列表来存储,不会影响到就列表。
使用extend
方法,相当于把一个列表拼接到另一个列表的后面。
a.extend(b)
是吧b的内容拼接到a的末尾,会改变a,但不会改变b。alist = [1,2,3]
blist = [4,5,6,7]
alist.extend(blist)
print(alist)
print(blist)
'''
[1, 2, 3, 4, 5, 6, 7]
[4, 5, 6, 7]
'''
13.9 关于元组
元组的功能和列表相比,基本一致的。
元组使用()
来表示
atuple = ()
atuple = tuple()
元组不能修改里面的元素,列表则可以修改里面的元素。
因此像一些读操作,比如访问下标,切片,遍历,in,index +
元组一样支持的。
但是像写操作 修改元素 新增元素 删除元素 extend
元组都是不支持的。
另外再python中很多时候默认的集合类型就是元组。
def test():
return 1,2
print(type(test()))
#<class 'tuple'>
为什么python即有列表又有元组呢?
元组的优势:
把你的列表数据弄乱. 那么这时候传一个元组就安全很多.
是一个hash表). 而一个可hash对象的前提就是不可变. 因此元组可以作为字典的键, 但是列表
不行
14. 字典
字典是一种存储键值对的结构。
和生活中的字典一样,当你查一个英语的意思时:apple就对应着苹果。它们就是一个键值对,其中apple就是key,而苹果就是value。
这些键(key)和值(value)是一一对应的,我们可以根据键,快速找到值。
14.1 创建字典
创建一个空的字典,使用{}
来表示字典。
a = {}
b = dict()
print(type(a))
print(type(b))
'''
<class 'dict'>
<class 'dict'>
'''
:
来分割。adict = {'apple': '苹果','world': '世界'}
print(adict)
# {'apple': '苹果', 'world': '世界'}
如果你想要代码更加的美观,好看,可以这样写:
adict = {
'apple': '苹果',
'world': '世界'
}
最后一个键值对,后面可写,
也可不写。
14.2 查找key
in
可以判断key是否在字典中存在,返回布尔值。adict = {
'apple': '苹果',
'world': '世界'
}
print('apple' in adict)
print('hello' in adict)
'''
True
False
'''
[]
通过类似下标访问的方式来获取元素的值,只不过这里的下标是key。adict = {
'apple': '苹果',
'world': '世界'
}
print(adict['apple'])
print(adict['world'])
'''
苹果
世界
'''
如果key值不存在,会抛出异常。
KeyError: 'xxxxx'
14.3 新增修改元素
使用[]
可以根据key来新增/修改value。
adict = {
'apple': '苹果',
'world': '世界'
}
adict['hello'] = '你好'
print(adict)
#{'apple': '苹果', 'world': '世界', 'hello': '你好'}
adict = {
'apple': '苹果',
'world': '世界'
}
adict['apple'] = '苹果苹果'
print(adict)
#{'apple': '苹果苹果', 'world': '世界'}
14.4 删除元素
adict = {
'apple': '苹果',
'world': '世界'
}
adict.pop('apple')
print(adict)
# {'world': '世界'}
14.5 遍历字典元素
adict = {
'apple': '苹果',
'world': '世界',
'hello': '你好'
}
for key in adict:
print(key,adict[key])
'''
apple 苹果
world 世界
hello 你好
'''
14.6 取出所有key和value
adict = {
'apple': '苹果',
'world': '世界',
'hello': '你好'
}
print(adict.keys())
# dict_keys(['apple', 'world', 'hello'])
values
方法可以获取到字典的所有valueadict = {
'apple': '苹果',
'world': '世界',
'hello': '你好'
}
print(adict.values())
#dict_values(['苹果', '世界', '你好'])
items
方法可以获取字典中的所有键值对。adict = {
'apple': '苹果',
'world': '世界',
'hello': '你好'
}
print(adict.items())
# dict_items([('apple', '苹果'), ('world', '世界'), ('hello', '你好')])
14.7 合法的key类型
不是所有的类型都可以作为字典的key的,字典的本质其实是哈希表,哈希表的key要求是可哈希的
,也就是可以计算出一个哈希值。
hash
函数计算某个对象的哈希值。print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(()))
'''
0
322818021289917443
7740487628353429172
1
5740354900026072187
'''
注意:
print(hash([1,2,3,4]))
#TypeError: unhashable type: 'list'
print(hash({'a': '0'}))
#TypeError: unhashable type: 'dict'
15.文件
15.1 文件是什么
变量是把数据保存到内存中,如果程序重启/断电,内存中的数据就会丢失。
要想实现数据的持久化存储,就需要把数据存储,就可以把数据存储到硬盘中,也就是在文件中存储。
一些常见的文件类型:
文本文件 txt
可执行文件 exe class
图片文件 jpg png
视频文件 mp4 mov
office文件 ppt docx
本文主要聚焦于文本文件。
15.2 文件路径
在系统中会存在特别多的文件,为了人让这些文件更加全面的被组织,往往会使用很多的文件夹,在Linux也叫目录。
实际上一个文件往往会进行许多的目录嵌套。为了方便确定一个文件的位置,使用文件路径来描述就很方便了。
以我存储python代码的路径为例D:\code\python
\
表示一级目录,当前的python就是放在D盘下的code目录下的。\
也可以使用/
一般在编写代码时使用/
更方便。绝对路径于相对路径:
在描述一个文件路径时,使用绝对路径还是相对路径都是可以的。
15.3 文件操作
要使用文件,主要通过文件来保存数据,并且在后续把保存数据调出来。为了读写文件,首先当然需要打开文件,在完成操作后在关闭文件。
15.3.1 打开文件
使用内建函数open
打开文件。
f = open('d:/test.txt','r')
r
表示按读方式打开,w
表示按照写方式打开,’a‘表示追加方式打开。15.3.2 关闭文件
使用close
方法关闭已打开的的文件。
f.close()
使用完毕的文件一定要记得关闭。
一个程序能同时打开的文件数是有限制的
flist = []
count = 0
while True:
f = open('d:/tmp/test.txt','r')
flist.append(f)
count+=1
print(f'count = {count}')
'''
...
count = 8187
count = 8188
count = 8189
Traceback (most recent call last):
File "d:\code\python\python_test1\test.py", line 158, in <module>
OSError: [Errno 24] Too many open files: 'd:/tmp/test.txt'
'''
从代码上来看,大概一个程序是可以打开8000个文件。如果一种循环的打开文件,而不去关闭,就会出现上述问题。当一个程序打开的文件超过上限,就会抛出异常。
上述代码中,使用一个列表来保存所有文件对象,如果不进行保存,那么python内置的垃圾回收机制就会在文件销毁的时候自动关闭文件。
但是由于垃圾回收机制不一定及时,所以我们写代码时仍然需要手动回收,避免依赖于自动回收。
15.3.3 写文件
文件打开后,就可以写文件了。
open
第二个参数为w
。write
方法写入文件。f = open('d:/tmp/test.txt','w')
f.write('i am yui')
f.close()
打开test.txt发现已经写入。
如果在r
方式下写入的话,程序会抛出异常。
使用
w
打开文件成功后,原有文件中的数据会清零。
使用a
实现追加写,此时原有内容不变,写入的内容会存在于之前文件内容的末尾。
f = open('d:/tmp/test.txt','w')
f.write('i am yui')
f.close()
f = open('d:/tmp/test.txt','a')
f.write(',hello')
f.close()
15.3.4 读文件
r
方式打开文件。read
方法完成读操作,参数表示读取几个字符
。f = open('d:/tmp/test.txt','r')
result = f.read(10)
print(result)
f.close()
'''
i am yui,h
'''
我们先构造一个多行的文本文件。
111111
222222
333333
444444
下面来打印这文件的内容。
f = open('d:/tmp/test.txt','r')
for line in f:
print(f'line = {line}')
f.close()
'''
line = 111111
line = 222222
line = 333333
line = 444444
'''
由于文件里每行的末尾都自带一个换行符,print打印的时候又会默认加上一个换行符,因此打印结果看起来之间存在空格。
使用
print(f'line = {line}',end='')
可以取代print自带的换行符。
readline
直接把文件整个内容读取出来,返回一个列表,每个元素即为一行。f = open('d:/tmp/test.txt','r')
lines = f.readlines()
print(lines)
f.close()
'''
['111111\n', '222222\n', '333333\n', '444444\n']
'''
15.4 关于中文的处理
当文件内容出现中文时,读取文件内容可能会出现错误。即出现乱码。
为什么会出现这种情况呢?
计算机表示中文的时候,会采取一定的编码方式,被称为字符集
所谓的“编码方式”,本质就是使用数字表示汉字。
众所周知,计算机只能表示二进制数据,要想表示英文字母或者汉字或者其他的文字字符,就就要通过编码。
最简单的字符编码ASCII,使用一个简单的整数就可以表示英文字母和数字,但是如果要表示汉字就需要更大的码表了。
目前常用的汉字编码方式主要是:GBK和UTF-8.
为此必须保证文件本身的编码方式,和python代码中读取文件使用的编码方式相一致,才能够避免出错。
python3默认打开文件的字符集跟随系统,而Windows简体中文版的字符集采用GBK,所以如果文件本身是GBK的编码,直接就能正确处理。如果不是的就会出错。
15.5 使用上下文管理器
打开文件后,最容易忘记的就是关闭。python提供了上下文管理器,来帮助我们自动关闭文件。
with open('d:/tmp/test.txt','r') as f:
lines = f.readlines()
print(lines)
'''
['111111\n', '222222\n', '333333\n', '444444\n']
'''
作者:Yui_