python基础学习

第一章 标识符

1、python 被称为胶水语言,可以跟各个代码能一块儿使用

爬虫、数据分析

web全栈开发、数据科学方向、人工智能的机械学习和深度学习、自动化运维、爬虫、办公自动化

python是跨平台的,python是解释型语言,不需要编译,python是面向对象的语言

1、print()

# print()可以输出数字、字符串、含有运算符的表达式
# print()可以将内容输出到显示器、文件
# print()输出形式换行、不换行
# 字符串可以使用单引号、双引号、三引号。目的是为了告诉计算机,不需要经行额外的处理
print(1)
print(3 + 2)
print('hello world')
print('hello', 'world', 'python')  # 不换行输出

# print() 输出到文件中,注意点 1、 所指定的盘符要存在。2、使用file=xx
fp = open('C:/Users/wb_zhouwei/PycharmProjects/text.txt', 'a+')  # 文件不存在就创建,文件存在就在文件内容最后面继续添加内容
print('hello world', file=fp)
fp.close()

2、转义字符 \

# 转义字符
# 就是反斜杠+想要实现功能的首字母

# 换行        \n
print('hello\nworld')
# 水平制表符   \t  每四个字母为一个制表位,正好占满,新开一个制表位,没占满补齐
print('hello\tworld')
print('hell\tworld')
# 回车        \r  用后面的覆盖前面的
print('helloo\rworld')
# 退格        \b  往前回退一个字母位
print('hello\bworld')

# \' \\ \"
print('周凯说:\'黄亮是傻逼\'')

# 原字符 不希望字符串中的转义字符起作用,就使用元字符,就是在字符串之前加r或R
print(r'及方式连接方式')
# print(r'技术的困窘\') 注意:字符串最后不能是单数个反斜杠,但是可以是双数个

3、二进制与字符编码

8 bit 表示一个字节 1 byte

1024 byte = 1 KB

MB GB TB

二进制=>ascll 码表 =>统一编码 Unicode =>utf-8

4、标识符和保留字

保留字
import keyword

print(keyword.kwlist)

输出结果:

    ['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

以上均为保留字

标识符:

变量,函数,类,模块和其他对象的起的名字就叫标识符

规则:

字母,数字,下划线

不能以数字开头

不能是保留字

严格区分大小写

第二章 数据类型

5、变量的定义和使用

name = ‘玛丽亚’

变量有三部分组成

标识:表示对象所从出的内存地址,使用内置函数id(obj)来获取

类型:表示的时对象的数据类型,使用内置函数type(obj)来获取

值:表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出

name = '玛丽亚'
print(name)

print('标识', id(name))
print('类型', type(name))
print('值', name)

name = '楚留冰'
print(name)

print('标识', id(name))
print('类型', type(name))
print('值', name)
玛丽亚
标识 2084983730320
类型 <class 'str'>
值 玛丽亚
楚留冰
标识 2084983731568
类型 <class 'str'>
值 楚留冰

当多次赋值之后,变量名会指向信的空间

6、python的数据类型

整数类型->int

浮点数类型->float

布尔类型->bool

字符串类型->str

整数类型

integer 简写为int 表示正数、负数和零

默认为十进制

二进制->以0b开头

八进制->以0o开头

十六进制->以0x开头

# 表示正数、负数、0
n1 = 90
n2 = - 76
n3 = 0

print(n1, type(n1))
print(n2, type(n2))
print(n3, type(n3))

# 正数可以表示二进制、八进制、十进制、十六进制

print('十进制', 118)
print('二进制', 0b10101111)  # 二进制以0b开头
print('八进制', 0o176)  # 八进制以0o开头
print('十六进制', 0xa8624)  # 十六进制以0x开头
浮点类型

浮点数分为整数部分和小数部分

浮点数存储不精确性

​ 使用浮点进行计算时,可能会出现小数不确定的情况

​ 原因:采用二进制进行存储的,导致精度不准确

n1= 1.1
print(n1 + 2.2)  # 3.3000000000000003
print(n1 + 2.1)  # 3.2

解决方案

​ 导入模块decimal

from decimal import Decimal
print(Decimal('1.1') + Decimal('2.2'))
布尔类型 boolean

用来表示真或假的值

True表示真,False表示假

布尔值可以转化为整数

True = 1

False= 0

f1 = True
f2 = False
print(f1, type(f1))
print(f2, type(f2))

print(f1 + 1)  # 2
print(f2 + 1)  # 1
字符串类型

又被称为不可变的字符序列

可以使用单引号’ ‘双引号" “三引号”’ '“或”“” “”"来定义

单引号和双引号定义的字符串必须在一行

三引号定义的字符串可以分布在连续的多行

str1 = '人生苦短,及时行乐'
str2 = "人生苦短,及时行乐"
str3 = """人生苦短,
    及时行乐"""

print(str1, type(str1))
print(str2, type(str2))
print(str3, type(str3))

# 人生苦短,及时行乐 <class 'str'>
# 人生苦短,及时行乐 <class 'str'>
# 人生苦短,
#     及时行乐 <class 'str'>
数据类型转换

为什么需要数据类型转换

​ 将不同数据类型的数据拼接在一起

str() 也可以使用引号转换

int()

​ 1、文字类和小数类的字符串,无法转换

​ 2、浮点数转换为整数,抹零取整

float()

​ 1、文字类的字符串无法转换成浮点数

​ 2、整数转换成浮点数,末尾多加.0

name = '张三'
age = 20

print(type(name), type(age))  # 说明name与age的类型不相同
print('我叫' + name + ',今年' + str(age) + '岁')  # 将int类型通过str()函数转成了str类型

print('-------------------str()将其他类型转成str类型----------------------')
a = 10
b = 198.12
c = False
print(type(a), type(b), type(c))

print(str(a), type(str(a)))
print(str(b), type(str(b)))
print(str(c), type(str(c)))

print('-------------------int()将其他类型转成int类型----------------------')
s1 = '128'
f1 = 98.7
s2 = '76.77'
ff = True
s3 = 'hello'
print(type(s1), type(f1), type(s2), type(ff), type(s3))
print(int(s1), type(int(s1)))
print(int(f1), type(int(f1)))
# print(int(s2), type(int(s2)))     报错  字符串为小数
print(int(ff), type(int(ff)))
# print(int(s3), type(int(s3)))     报错  字符串必须是数字串(整数),非数字串是不允许转换的


print('-------------------float()将其他类型转成float类型----------------------')
s1 = '128.98'
s2 = '76'
s3 = 'hello'
ff = True
i = 98
print(type(s1), type(s2), type(s3), type(ff), type(i))
print(float(s1), type(float(s1)))
print(float(s2), type(float(s2)))
print(float(ff), type(float(ff)))
# print(float(s3), type(float(s3))) 字符串中的数据如果为非数据串,则不允许转换
print(float(i), type(float(i)))

7、python中的注释

注释是给人看的,注释内容会被python解释器忽略

单行注释 #

多行注释 并没有单独的多行注释标记,将一对三引号之间的代码成为多行注释

中文编码声明注释 再文件开头加上中文声明注释,用以指定源码文件的编码格式 #coding:gbk (python3不用)

# 输出功能   单行注释
print('hello')
"""
这就是
多行注释
"""

第三章 运算符

8、python的输入函数input()

作用:接受来自用户的输入

返回值类型:输入值的类型str

值的存储:使用=对输入的值进行存储

# 输入函数input
present = input('大圣想要什么礼物呢?')
print(present, type(present))

# 大圣想要什么礼物呢?ding
# ding <class 'str'>

作业:

# 从键盘录入两个整数,计算整数的和
a = input('请输入第一个整数:')
b = input('请输入第二个整数:')

print(int(a) + int(b))

# 请输入第一个整数:10
# 请输入第二个整数:20
# 30

# 优化:

a = int(input('请输入第一个整数:'))
b = int(input('请输入第二个整数:'))
print(a + b)

9、python中的运算符

算术运算符
标准运算符

​ 加(+)、减(-)、乘(*)、除(/)、整除(//)

print(1 + 1)  # 加法运算    2
print(2 - 1)  # 减法运算    1
print(2 * 4)  # 乘法运算    8
print(1 / 2)  # 除法运算    0.5
print(11 // 2)  # 整除运算  5

print(9 / -4) # -2.25

print(9 // 4)  # 2
print(-9 // -4)  # 2
print(9 // -4)  # -3
print(-9 // 4)  # -3
# 一正一负的整除公式,向下取整

所有的整除公式,都是向下取整

取余运算符

​ 取余 %

print(11 % 2)  # 取余运算   1  11-2*5 = 1

print(9 % -4)  # -3     9-(-4)*(-3) = -3
print(-9 % 4)  # 3		-9-4*(-3) = 3
# 余数 = 被除数-除数*商

余数 = 被除数-除数*商(整除的商)

幂运算符

​ 幂运算 **

print(2 ** 3)  # 2的3次方  8
赋值运算符
执行顺序

右到左:将右边的值赋值给左边

支持链式赋值: a=b=c=20

支持参数赋值:+=、-+、*=、/=、//=、%=

支持系列解包赋值:a,b,c=20,30,40 **注意:**左右两边个数要相同

i = 3 + 4
print(i)

print('--------支持链式赋值-----------')
a = b = c = 20  # a b c 的引用都指向同一个对象
print(a, id(a))
print(b, id(b))
print(c, id(c))
print('-------------------支持参数赋值------------------------')
a = 20
a += 30
print(a)  # 50
a -= 10
print(a)  # 40
a *= 2
print(a, type(a))  # 80 <class 'int'>
a /= 3
print(a, type(a))  # 26.666666666666668 <class 'float'>
a //= 2
print(a, type(a))  # 13.0 <class 'float'>
a %= 3
print(a)  # 1.0
print('-------------------支持系列解包赋值------------------------')
a, b, c = 20, 30, 40
print(a, b, c)  # 20 30 40
print('----------交换两个变量的值----------')
a, b = 10, 20
print('交换之前:', a, b) #	交换之前: 10 20
# 交换
a, b = b, a
print('交换之后:', a, b) #	交换之后: 20 10
比较运算符

定义:对变量或者表达式的结果进行大小,真假等比较 结果为boolean类型

< 、> 、<= 、>=、 !=

== 对象value的比较

is,is not 对象id的比较

a, b = 10, 20
print('a>b吗?', a > b)  # False
print('a<b吗?', a < b)  # True
print('a<=b吗?', a <= b)  # True
print('a>=b吗?', a >= b)  # False
print('a==b吗?', a == b)  # False
print('a!=b吗?', a != b)  # True
"""  
    = 称为赋值运算符      == 称为比较运算符
    一个变量有三个部分组成,标识,类型,值
    == 比较的是两个对象的值
    比较对象的标识使用的是   is  is not
"""
a = 10
b = 10
print(a == b)  # True   说明a与b的value,相等
print(a is b)  # True   说明a与b的id标识,相等
print(a is not b)  # False 

lst1 = [11, 22, 33, 44]
lst2 = [11, 22, 33, 44]
print(lst1 == lst2)  # True
print(lst1 is lst2)  # False
print(lst1 is not lst2)  # True
print(id(lst1))  # 3100263766848
print(id(lst2))  # 3100263605248
布尔运算符

and 并且

or 或者

ont 取反

in

not in

# 布尔运算符
print('--------------------and  并且-------------------------')
a, b = 10, 20
print(a == 10 and b == 20)
print(a == 10 and b < 20)
print(a != 10 and b == 20)
print(a != 10 and b != 20)

print('--------------------or  或者-------------------------')
print(a == 10 or b == 20)
print(a == 10 or b < 20)
print(a != 10 or b == 20)
print(a != 10 or b != 20)

print('--------------------not  布尔类型的操作数取反-------------------------')
f = True
f2 = False
print(not f)
print(not f2)

print('--------------------in  包含-------------------------')
s = 'helloworld'
print('w' in s)
print('k' in s)
print('w' not in s)
print('k' not in s)
位运算符

位与 & 对应数位都是1,结果才为1,否则为0

位或 | 对应数位都是0,结果才是0,否则为1

左移运算符 << 高位溢出舍弃,地位补0

右移运算符 >> 低位溢出舍弃,高位补0

print(4 & 8)  # 0 # 按位& 同为1时结果为1,否则为0
print(4 | 8)  # 12 # 按位| 同为0时结果为0,否则为1
print(4 << 1)  # 8
print(4 >> 1)  # 2

10、运算符的优先级

**

*,/,//,%

+,- 算术运算符先算乘除,再算加减,有幂运算最先算

<<,>>

&

| 位运算

<,>,<=,>=,==,!= 比较运算符

and

or 布尔运算符

= 赋值运算符

右括号先算括号里面的

总结:

() 、算数运算、位运算、比较运算、布尔运算、赋值运算

第四章 往哪儿走 分支结构

11、程序的组织结构

顺序结构、选择结构、循环结构

12、顺序结构

从上往下依次执行

13、对象的布尔值

python中一切皆对象,所有对象都有一个布尔值
	获取对象的布尔值
		使用内置函数bool()

以下对象的布尔值为False
False
数值0
None
空字符串
空列表
空元组
空字典
空集合
# 测试对象的布尔值
print(bool(False))  # False     False
print(bool(0))  # False         数值0
print(bool(0.0))  # False       数值0
print(bool(None))  # False      None
print(bool(''))  # False        空字符串
print(bool(""))  # False        空字符串
print(bool([]))  # False        空列表
print(bool(list()))  # False    空列表
print(bool(()))  # False        空元组
print(bool(tuple()))  # False   空元组
print(bool({}))  # False        空字典
print(bool(dict()))  # False    空字典
print(bool(set()))  # False     空集合

print('---------------------其他对象的布尔值均为True-------')
print(bool(18))  # True
print(bool(True))  # True
print(bool('hello'))  # True

主要目的:可以让if后面直接跟非布尔值(对象)

age = int(input('请输入您的年龄:'))
if age:
    print(age)
else:
    print('年龄不合法!')
# 请输入您的年龄:0
# 年龄不合法!

14、分支结构

又称为选择结构

单分支if结构

​ 语法结构

if 条件表达式 :
	条件执行体
money = 1000
i = int(input('请输入取款金额!'))
if money >= i:
    money -= i
    print('取款成功,余额为:', money)
双分支if…else结构
if 条件表达式 :
	条件执行体1
else:
	条件执行体2
# 从键盘录入一个整数,判断是奇数还是偶数
s = int(input('请输入一个整数'))
if s % 2 == 1:
    print(s, '该数值为奇数')
else:
    print(s, '该数值为偶数')
多分支结构
if 条件表达式:
	条件执行体1
elif 条件表达式:
	条件执行体2
else:
	条件执行体3
'''
多分支结构,多选一
从键盘录入一个整数 成绩
90-100      A
80-89       B
70-79       C
60-69       D
0-59        E
小于0或大于100  为非法数据
'''
score = int(input('请输入一个成绩:'))

if 90 <= score <= 100:
    print('A')
elif 80 <= score <= 89:
    print('B')
elif 70 <= score <= 79:
    print('C')
elif 60 <= score <= 69:
    print('D')
elif 0 <= score <= 59:
    print('E')
else:
    print('成绩输入有误!')

数学比较,只有python能够这样写

if语句的嵌套
条件表达式

条件表达式是if…else…的简写

语法结构:

​ x if 判断条件 else y

运算规则:

判断条件为True,条件表达式的返回值为x,否则条件表达式的返回值为False

'''从键盘录入两个整数,比较两个整数的大小'''
num_a = int(input('请输入第一个整数'))
num_b = int(input('请输入第一个整数'))
print('大的整数为:', num_a if num_a > num_b else num_b)

15、pass空语句

pass语句
	语句什么都不做,只是一个占位符,用在语法上需要的地方

什么时候使用:
	先搭建语法结构,还没想好代码怎么写的时候

哪些语句一起使用:
	if语句的条件执行体
	for-in语句的循环体
	定义函数时的函数体
# pass 语句什么都不做,只是一个占位符,用到需要写语句的地方

answer = input('您是会员吗?y/n')

if answer == 'y':
    pass
else:
    pass

对象布尔值的作用

主要目的:可以让if后面直接跟非布尔值

age = int(input('请输入您的年龄:'))
if age:
    print(age)
else:
    print('年龄不合法!')
# 请输入您的年龄:0
# 年龄不合法!

第五章 转圈圈 循环结构

16、range()函数

内置函数range()、print()、input(),内置函数时不需要导包,直接可以使用的函数

range()函数:

​ 用于生成一个整数序列
​ 创建range对象的三个方式

	range(stop)  # 创建一个[0,stop)之间的整数序列,步长为1
	range(start,stop)# 创建一个[start,stop)之间的整数序列,步长为1
	range(start,stop,step)# 创建一个[start,stop)之间的整数序列,步长为step

​ 返回值是一个迭代器对象

​ range类型的有点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为只需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素

​ in与not in可以判断整数序列中是否存在指定的整数

# 第一种创建方式
r = range(10)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  默认cong0开始,步长为1
print(r)  # range(1,10)
print(list(r))  # 用于查看range对象中的整数序列-->list是列表的意思
# 第二种创建方式
r = range(1, 10)  # 制定了起始值,从1开始,到10结束(不包含10),默认步长为1
print(list(r))  # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 第三种方式
r = range(1, 10, 2)
print(list(r))  # [1, 3, 5, 7, 9]

# 判断指定的数再序列中是否存在
print(10 in r)  # False
print(10 not in r)  # True
print(9 in r)  # True

17、while循环

语法结构:

while 条件表达式:

​ 条件执行体(循环体)

a = 1
while a < 10:
    print(a)
    a += 1
    
# 计算0到4之间的累加和
'''
1、初始化变量
2、判断条件
3、条件执行体(循环体)
4、改变变量
总结:初始化的变量与条件判断的变量与改变的变量为统一个
'''
a = 0
sum = 0  # 用于存储累加的值
while a < 5:
    sum += a
    a += 1
print('和为:', sum)


# 计算1到100之间的偶数和
a = 1
sum = 0
while a <= 100:
    if a % 2 == 0:  #可以改进为if not bool(a%2):   数值0为False
        sum += a
    a += 1
print(sum) #2550

18、for-in循环

in表达从字符串序列中依次取值,又称为遍历

for-in便利的对象必须是可迭代对象

语法结构:

for 自定义的变量 in 可迭代对象:

​ 循环体

循环体内不需要访问自定义变量时,可以将自定义变量代替为下划线

for item in 'Python':
    print(item)

# range()产生一个整数序列,-->也是一个可迭代对象
for i in range(10):
    print(i)

# 如果在循环体中,不需要自定义变量,可用_代替自定义变量
for _ in range(5):
    print('人生几何')

print('使用for计算1到100的偶数和')
sum = 0
for i in range(1, 101):
    if not bool(i % 2):
        sum += i
print(sum)
# 输出100到999之间的水仙花数

for item in range(100, 1000):
    ge = item % 10
    shi = item // 10 % 10
    bai = item // 100
    if item == ge ** 3 + shi ** 3 + bai ** 3:
        print(item)

19、break、continue与else语句

break用于结束整个循环结构,通常与分支结构if一起使用

continue用于结束当前循环,进入下次循环,通常与分支结构if一起使用

else 分支结构中,if条件表达式不成立时执行else

如果循环语句正常结束(没有碰到break)时执行else语句**

# for循环
for item in range(3):
    pwd = input('请输入密码:')
    if pwd == '8888':
        print('密码正确!')
        break
    else:
        print('密码不正确!')
else:
    print('您今日的次数已经用完,请明天再试')
    
    
# while循环    
a = 0
while a < 3:
    pwd = input('请输入密码:')
    if pwd == '8888':
        print('密码输入正确!')
        break
    else:
        print('密码输入错误!')
    a += 1
else:
    print('您今日的次数已经用完,请明天再试')

20、嵌套循环

# 输出三行四列的矩形
for i in range(3):
    for j in range(4):
        print('*', end='\t')  # 不换行输出
    print()

执行结果:

*	*	*	*	
*	*	*	*	
*	*	*	*
# 打印99乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        a = i * j
        print(str(i) + '*' + str(j) + '=' + str(a), end='\t')  # 不换行输出
    print()

二重循环中的break和continue用于控制本层的循环 即为就近原则

最多别超过三层

第六章 一字排开 列表

21、列表的创建与删除

变量可以存储一个元素,而列表是一个”大容器“可以存储N多个元素,程序可以方便地对这些数据进行整体操作

列表相当于其他语言的数组 存的内容不一定是同一个类型

a = 10  # 变量存储的是一个对象的引用
# 列表创建方式一
lst = ['hello', 'world', 98]
# 列表创建方式二
lst = list(['hello', 'world', 98])
print(id(lst))  # 指得是列表本身的id  列表中的每个空间存的是对象的内存地址
print(type(lst))

创建方式

lst = [‘大圣’,‘金克拉撒旦’]

lst = list([‘大圣’,‘金克拉撒旦’])

列表的特点

列表元素按顺序有序排序  	第一个放的排在第一个
索引映射唯一个数据		从左往右为顺序,从0开始依次递增;从右往左为倒序,从-1开始依次递减
列表可以存储重复的数据
任意数据类型混存
根据需要动态分配和回收内存

22、列表的查询

获取列表中的单个元素

获取列表中指定元素的索引

获取列表中指定索引的元素

# 获取列表中指定元素的索引
lst = ['hello', 'world', 98, 'hello']
print(lst.index('hello'))  # 0  如果列表中有相同元素,只返回列表中相同元素的第一个元素的索引
# print(lst.index('python')) 查找不存在的元素,回抛出异常ValueError
print(lst.index('hello', 1, 4))  # 从索引[1,4)之间查找'hello'元素  左闭右开

# 获取列表中指定索引的元素
lst2 = ['hello', 'world', 98, 'hello', 'world', 234]
print(lst2[2])
print(lst2[-3])
# print(lst2[10]) # IndexError: list index out of range 索引超出范围会报错
获取列表中的多个元素:切片操作
语法格式:列表名[start : stop : step]    左闭右开
切片结果:原列表片段的拷贝
切片的范围:[start : stop]
step默认为1:可简写为[start : stop]
step为正数:从start开始往后计算切片
step为负数:从start开始计算往前切片
lst = [10, 20, 30, 40, 50, 60, 70, 80]
# start =1 ,stop = 6,step =1
# print(lst[1:6:1])
print('原列表', id(lst))
lst2 = lst[1:6:1]
print('切片得到的列表', id(lst2))  # 切片得到新的列表
# 默认步长为1
print(lst[1:6])  # [20, 30, 40, 50, 60]
print(lst[1:6:])  # [20, 30, 40, 50, 60]
print(lst[1:6:2])  # [20, 40, 60]
# 省略start
print(lst[:6:2])  # [10, 30, 50]
# 省略stop
print(lst[1::2])  # [20, 40, 60, 80]
print('______________________步长为负数的情况________________________')
print('原列表', lst)
print(lst[::-1])  # [80, 70, 60, 50, 40, 30, 20, 10]
# start = 7 stop省略 step= -1
print(lst[7::-1])  # [80, 70, 60, 50, 40, 30, 20, 10]
# start = 6 stop =0 step =-2
print(lst[6:0:-2])  # [70, 50, 30]
判断指定元素在列表中是否存在
列表元素的遍历
判断指定元素在列表中是否存在
元素 in 列表名
元素 not in 列表名
列表元素的遍历
for 迭代变量 in列表名 :
	操作
print('p' in 'python')  # True

lst = [10, 20, 'python', 'hello']
print(10 in lst)  # True
print(100 in lst)  # False
print('p' in lst)  # False

print('-----------------遍历列表------------------------')
for item in lst:
    print(item)

23、列表元素的增、删、改操作

列表元素的增加操作
append()  在列表末尾添加一个元素
extend()  在列表末尾添加至少一个元素
insert()  在列表的任意位置上插入一个元素(指定位置添加元素)
切片   在列表的任意位置添加至少一个元素
lst = [10, 20, 30]
print('添加元素之前', lst, id(lst))
lst.append(40)
print('添加元素之后', lst, id(lst))  # [10, 20, 30, 40]

lst2 = ['hello', 'world']
# lst.append(lst2)
# print(lst)  # [10, 20, 30, 40, ['hello', 'world']]  lst2作为一个元素添加到列表当额末尾
lst.extend(lst2)
print(lst)  # [10, 20, 30, 40, 'hello', 'world'] 在列表末尾添加至少一个元素
# 在任意位置上插入一个元素
lst.insert(1, 90)
print(lst)  # [10, 90, 20, 30, 40, 'hello', 'world']
# 切片添加多个元素
lst3 = [True, False, 'hello']
lst[1:] = lst3
print(lst)  # [10, True, False, 'hello']
列元素的删除操作
remove() 一次删除一个元素,重复元素只删除第一个,元素不存在抛出ValueError
pop() 		删除一个指定索引位置上的元素,指定索引不存在抛出IndexError,不指定索引则默认删除列表中最后一个元素
切片			一次至少删除一个元素
clear() 	清空列表
del			删除列表
lst = [10, 20, 30, 40, 50, 60, 30]
lst.remove(30)
print(lst)  # [10, 20, 40, 50, 60, 30]   从列表中移除一个元素,如果有重复元素,只移除第一个元素,如果元素不存在,ValueError

lst.pop(1)
print(lst)  # [10, 40, 50, 60, 30]  移除指定索引位置的元素,索引超出IndexError,pop后面不指定参数,默认删除列表最后一个元素

print('----------------切片操作:删除至少一个元素,但是将产生一个新的操作-----------------------')
new_lst = lst[1:3]
print(new_lst)  # [40, 50]

'''不产生新的列表对象,而是删除原列表的内容'''
lst[1:3] = []
print(lst)  # [10, 60, 30]

'''清除列表中的所有元素'''
lst.clear()
print(lst)  # []

'''del语句将删除列表对象'''
del lst
print(lst)  # NameError: name 'lst' is not defined  名字没有定义对象
列表元素的改操作

为指定索引的元素赋予一个新值

为指定的切片赋予多个新值

lst = [10, 20, 30, 40]
# 一次修改一个值
lst[2] = 100
print(lst)  # [10, 20, 100, 40]

lst[1:3] = [300, 400, 500, 600]
print(lst)  # [10, 300, 400, 500, 600, 40]   将中间的20,100,替换成了300,400,500,600

24、列表元素的排序

常见的两种方式
调用sort()方法,列表中的所有元素默认按从小到大排序,可以指定reverse = True,进行降序排序

调用内置函数sorted(),可以指定reverse = True,进行降序排序,原列表不发生改变

lst = [20, 40, 58, 10, 98, 54]
print('排序前的内容', lst, id(lst))
# 调用列表对象的sort方法,默认是升序
lst.sort()
print('排序后的列表', lst, id(lst))
# 通过指定参数,将列表中的元素进行降序排序

lst.sort(reverse=True)  # reverse =True 表示降序   reverse = False 表示升序
print(lst)

print('---------------使用内置函数sorted()对列表进行排序,将产生一个新的列表')
lst2 = [20, 40, 58, 10, 98, 54]
new_lst = sorted(lst)
print(lst2)  # [20, 40, 58, 10, 98, 54]
print(new_lst)  # [10, 20, 40, 54, 58, 98]
# 指定关键字参数,实现列表的元素的降序排序
desc_lst = sorted(lst2, reverse=True)
print(desc_lst)# [98, 58, 54, 40, 20, 10]

25、列表推导式:生成式

即生成列表的公式

# [i for i in range(1,10)]
lst = [i * i for i in range(1, 10)]
print(lst)  # [1, 4, 9, 16, 25, 36, 49, 64, 81]
lst2 = [i * 2 for i in range(1, 6)]
print(lst2)  # [2, 4, 6, 8, 10]

第七章 夫妻站 字典

26、什么是字典

python内置的数据结构之一,与列表一样是一个可变序列
以键值对的方式存储数据,字典是一个无序的序列(存放无序)
scores={‘张三’:100,‘李四’:98,‘王五’:45}

存放原理:对key进行hash计算,计算完的值就是存放的位置,所以key必须是不可变序列(例如:字符串,整数序列)

27、字典的原理

**字典的实现原理:**字典的实现原理与查字典类似,查字典是先根据部首或拼音查找汉字对应的页码,python中的字典是根据key查找value所在的位置

28、字典的创建与删除

创建
最常使用的方式:使用花括号
scores={'张三':100,'李四':98,'王五':45}
使用内置函数dict()
dict(name ='jack',age = 20)
# 字典的创建方式
'''使用{}创建字典'''
scores = {'张三': 100, '李四': 98, '王五': 45}
print(scores)  # {'张三': 100, '李四': 98, '王五': 45}
print(type(scores))  # <class 'dict'>

'''第二种创建方式dict()'''
student = dict(name='jack', age=20)
print(student)  # {'name': 'jack', 'age': 20}

# 空字典
d = {}
print(d)  # {}

29、字典的查询操作

字典元素的获取
scores['张三']
scores.get('张三')
[]和get()区别:

[]如果不存在指定的key,抛出keyError异常
get()方法取值,如果不存在指定的key,并不会抛出keyError而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回

# 获取字典中的值
scores = {'张三': 100, '李四': 98, '王五': 45}
'''第一种方法,使用[]'''
print(scores['张三'])  # 100
# print(scores['陈六'])# KeyError: '陈六'

'''第二种方法,使用get()方法'''
print(scores.get('张三'))  # 100
print(scores.get('陈六'))  # None
print(scores.get('麻七', 99))  # 99  在查找'麻七'指定的value不存在时,提供的一个默认值
key的判断

in、not in

'''key的判断'''
scores = {'张三': 100, '李四': 98, '王五': 45}
print('张三' in scores)  # True
print('张三' not in scores)  # False

30、字典元素的增删改操作

字元素的删除操作

del scores[‘张三’]

# 删除指定的字典元素(键值对)
scores = {'张三': 100, '李四': 98, '王五': 45}
del scores['张三']
print(scores)  # {'李四': 98, '王五': 45}

scores.claer()   # 字典元素的清空操作
print(scores)# {}
字典元素的新增和修改操作

scores[‘jack’]= 90

# 新增字典元素
scores = {'张三': 100, '李四': 98, '王五': 45}
scores['jack'] = 90
print(scores)  # {'李四': 98, '王五': 45, 'jack': 90}
# 修改操作
scores['jack'] = 100
print(scores)  # {'李四': 98, '王五': 45, 'jack': 100}

31、获取字典视图

keys()    获取字典中所有key
values()  获取字典中所有value
items()	  获取字典中所有key,value对
scores = {'张三': 100, '李四': 98, '王五': 45}
# 获取所有的key
keys = scores.keys()
print(keys)  # dict_keys(['张三', '李四', '王五'])
print(type(keys))  # <class 'dict_keys'>
print(list(keys))  # ['张三', '李四', '王五']  通过内置的list()函数将keys转换成列表格式

# 获取所有的值value
values = scores.values()
print(values)  # dict_values([100, 98, 45])
print(type(values))  # <class 'dict_values'>
print(list(values))  # [100, 98, 45] 通过内置的list()函数将keys转换成列表格式

# 获取所有的键值对
items = scores.items()
print(items)  # dict_items([('张三', 100), ('李四', 98), ('王五', 45)])
print(type(items))  # <class 'dict_items'>
print(list(items))  # [('张三', 100), ('李四', 98), ('王五', 45)]  转换之后的列表元素是由元组组成

32、字典元素的遍历

for item in scores:
	print(item)
# 字典元素的遍历
scores = {'张三': 100, '李四': 98, '王五': 45}
for item in scores:
    print(item, scores.get(item), scores[item])
'''
张三 100 100
李四 98  98
王五 45  45
'''

33、字典的特征

字典中的所有的元素都是一个key-value对,key不允许重复,value可以重复
重点中的元素时无序的
字典中的key必须是不可变对象
字典也可以根据需要动态的伸缩
字典会浪费较大的内存,是一种用空间换时间的数据结构
d = {'name': '张三', 'name': '李四'}
print(d)  # {'name': '李四'} key不允许重复,会覆盖

d = {'name': '张三', 'nikename': '张三'}
print(d)  # {'name': '张三', 'nikename': '张三'}

lst = [10, 20, 30]
lst.insert(1, 100)
print(lst)  # [10, 100, 20, 30]   字典无法做到此操作
d = {lst: 100}
print(d)  # TypeError: unhashable type: 'list'  列表为可变对象,不可以作为key

34、字典生成式

内置函数zip()

​ 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表

​ 可迭代表示可以遍历

items = ['Fruits', 'Books', 'Others']
prices = [96, 78, 89, 100, 200, 120]

lst = zip(items, prices)
print(list(lst))  # [('Fruits', 96), ('Books', 78), ('Others', 89)]

d = {item.upper(): price for item, price in zip(items, prices)}  # upper()表示转换成大写
print(d)  # {'FRUITS': 96, 'BOOKS': 78, 'OTHERS': 89}

当两个列表的长度不相等时,zip()函数会以短的那个作为基准压缩打包

字典生成式:d={item:price for item,price in zip(items,prices)}

第八章 是排还是散 元组和集合

35、什么是元组

python内置的数据结构之一,是不可变序列

不可变序列与可变序列

不可变序列:字符串、元组
	不可变序列没有增删改操作

可变序列:列表、字典
	可变序列可以对序列执行增删改操作,对象的地址不会发生更改
'''不可变序列  可变序列'''
'''可变序列:列表、字典'''
lst = [10, 20, 30]
print(lst, id(lst))  # [10, 20, 30] 3147123252992
lst.append(40)
print(lst, id(lst))  # [10, 20, 30, 40] 3147123252992

'''不可变序列:字符串、元组'''
s = 'hello'
print(s, id(s))  # hello 3118496028080
s = s + 'world'
print(s, id(s))  # helloworld 3118498180400

36、元组的创建方式

t=('python','张三',90)
t=tuple(('python','张三',90))
只包含一个元组的元素需要用逗号和小括号
t=( 10, )
'''第一种创建方式'''
t = ('python', 'hello', 90)
print(t, type(t))  # ('python', 'hello', 90) <class 'tuple'>
t2 = 'python', 'hello', 98
print(t2, type(t2))  # ('python', 'hello', 98) <class 'tuple'>  一个元组多个元素时,可以省略小括号

'''第二种创建方式'''
t = tuple(('python', 'hello', 90))
print(t, type(t))  # ('python', 'hello', 90) <class 'tuple'>

t3 = (10)
print(t3, type(t3))  # 10 <class 'int'>
t = (10,)
print(t, type(t))  # (10,) <class 'tuple'>  当元组中只有一个元素时,必须要有小括号和逗号,否则为该元素本身的数据类型

'''空列表的常见方式'''
lst = []
lst1 = list()
print('空列表', lst, lst1)  # 空列表 [] []
'''空字典的常见方式'''
d = {}
d = dict()
print('空字典', d, d2)  # 空字典 {} {}
'''空元组的常见方式'''
t4 = ()
t5 = tuple()
print('空元组', t4, t5)  # 空元组 () ()

37、元组被设计为不可变序列的原因

在多任务环境下,同时操作对象是不需要加锁,因此,在程序中尽量使用不可变序列
(多线程)
注意事项:
	元组中存储的是对象的引用(深拷贝与浅拷贝)
	a)如果元组中对象本身为不可变对象,则不能在引用其他对象
	b)如果元组中的对象是可变对象,则可变对象的引用不允许改变,但是数据可以改变
t = (10, [20, 30], 9)
print(t)  # (10, [20, 30], 9)
print(type(t))  # <class 'tuple'>
print(t[0], type(t[0]), id(t[0]))  # 10 <class 'int'> 2983042837072
print(t[1], type(t[1]), id(t[1]))  # [20, 30] <class 'list'> 2983080812480
print(t[2], type(t[2]), id(t[2]))  # 9 <class 'int'> 2983042837040

'''尝试将t[1]修改为100'''
# 元组是不允许修改元素的
# t[1] = 100  # TypeError: 'tuple' object does not support item assignment
'''由于[20,30]咧白哦,而列表是可变序列,所有可以对列表中的数据进行修改,而列表的内存地址不变'''
t[1].append(99)
print(t[1], id(t[1]))  # [20, 30, 99] 1774169087552

38、元组的遍历

元组是可迭代对象,

'''元组的遍历'''
t = ('python', 'world', 98)
'''第一种获取元组元素的方式,使用索引'''
print(t[0])
print(t[1])
print(t[2])
# print(t[3]) 会出行索引越界

'''第二种获取元素的方式,for...in'''
for item in t:
    print(item)

39、什么是集合

python语言提供的内置数据结构
与列表、字典一样都属于可变类型的序列
集合是没有value值的字典
底层数据结构也是通过哈希表计算的

# 集合的创建方式
'''第一种创建方式:使用{}'''
s = {1, 2, 3, 4, 5, 7, 7}  # 集合中不允许出现重复的元素,会自动删除重复元素
print(s, type(s))  # {1, 2, 3, 4, 5, 7} <class 'set'>
'''第二种创建方式:使用内置函数set()'''
s1 = set({10, 20, 30, 40, 50})
print(s1, type(s1))  # {50, 20, 40, 10, 30} <class 'set'>

s2 = set(range(6))
print(s2, type(s2))  # {0, 1, 2, 3, 4, 5} <class 'set'>

s3 = set([33, 55, 88, 46, 33])  # 将列表转换成集合
print(s3, type(s3))  # {88, 33, 46, 55} <class 'set'>

s4 = set((1, 2, 3, 3, 4, 5, 6, 65))  # 将元组转换为集合
print(s4, type(s4))  # {1, 2, 3, 4, 5, 6, 65} <class 'set'>

s5 = set('python')  # 将字符串转换成集合
print(s5, type(s5))  # {'p', 'o', 't', 'h', 'y', 'n'} <class 'set'>

'''定义空集合'''
# s6 = {}     {} <class 'dict'>  这样只会创建一个空字典
s6 = set()
print(s6, type(s6))  # set() <class 'set'>

40、集合元素的常用操作

判断操作:in 或者 not in

新增操作:
add()
update()

删除操作:
remove()
discard()
pop()
clear()

# 集合元素的相关操作
'''集合元素的判断操作'''
s = {10, 20, 30, 405, 60}
print(10 in s)  # True
print(100 not in s)  # True

'''集合元素的新增操作'''
s.add(80)  # 一次添加一个元素
print(s)  # {80, 20, 405, 10, 60, 30}
s.update([200, 400, 300])  # 至少添加一个元素,元素类型可以是集合、列表、元组
print(s)  # {200, 10, 80, 400, 20, 405, 30, 300, 60}

'''集合元素的删除操作'''
s.remove(200)
print(s)  # {10, 80, 400, 20, 405, 30, 300, 60}
# s.remove(500)  # remove操作必须要求集合中存在该元素,否则报异常KeyError: 500

s.discard(500)  # discard也是删除操作,如果集合中不存在该元素,不会报异常
print(s)  # {10, 80, 400, 20, 405, 30, 300, 60}

s.pop()  # 没有参数,随机删除一个元素
print(s)  # {80, 400, 20, 405, 30, 300, 60}

s.clear()  # 清空集合
print(s)  # set()

41、集合之间的关系

两个集合是否相等
可以使用==或者!=进行判断

一个集合是否是另一个集合的子集
调用issubset经行判断

一个集合是否是另一个集合的超集
调用issuperset函数经行判断

两个集合是否没有交集
调用isdisjoint进行判断

s1 = {10, 20, 30, 40}
s2 = {40, 30, 20, 10}
print(s1 == s2)  # True
print(s1 != s2)  # False

s3 = {10, 20, 30}
print(s3.issubset(s1))  # s3是s1的子集  True
print(s1.issuperset(s3))  # s1是s3的超集 True

s4 = {10, 200, 300}
print(s1.isdisjoint(s4))  # s1与s3有交集  False   有交集为False,没有交集为True  判断是否没有交集

42、集合的数学操作

交集:两个集合取共同部分的数据(集合)

并集:两个集合合并在一起

差集:某一个集合去除跟另一个集合的交集

对称差集:两个集合去除交集

s1 = {10, 20, 30, 40}
s2 = {20, 30, 40, 50, 60}
# 交集操作
print(s1.intersection(s2))  # {40, 20, 30}  取交集
print(s1 & s2)  # {40, 20, 30} 等同于intersection  交集

# 并集操作
print(s1.union(s2))  # {40, 10, 50, 20, 60, 30} 取并集
print(s1 | s2)  # {40, 10, 50, 20, 60, 30} 等同于union 并集

# 差集操作
print(s1.difference(s2))  # {10}  s1不同于s2的数据
print(s1 - s2)  # {10}

# 对称差集操作
print(s1.symmetric_difference(s2))  # {50, 10, 60} 减去两个集合的交集
print(s1 ^ s2)  # {50, 10, 60}

43、集合的生成

没有元组的生成式

{i*i for i in range(1,10)}

# 列表生成式
lst = [i*2 for i in range(6)]
print(lst)

# 集合生成式
s = {i*2 for i in range(6)}
print(s)

44、列表、字典、元组、集合总结

数据结构是否可变是否重复是否有序定义符号
列表(list)可变可重复有序[]
元组(tuple)不可变可重复有序()
字典(dict)可变key不可重复,value可重复无序{key:value}
集合(set)可变不可重复无序{}
元组

创建()或者tuple()

遍历for…in

集合

创建{}或者set{}或者集合生成式

遍历for…in

新增add()或者update()

删除remove()或者descard()或者pop()或者clear()

第九章 一串连一串 字符串的常用操作

45、字符串的驻留机制

python中的字符串是基本数据类型,是一个不可变序列

字符串的驻留机制相当于java中的字符串常量池

# 字符串的驻留机制

a = 'python'
b = "python"
c = '''python'''

print(a, id(a))  # python 2233770193072
print(b, id(b))  # python 2233770193072
print(c, id(c))  # python 2233770193072
字符串驻留机制的几种情况(交互模式):
字符串驻留机制的几种情况(交互模式):
	字符串的长度为0或者1时
	符合标识符的字符串
	字符串只在编译时进行驻留,而非运行时
	[-5,256]之间的整数数字
	
sys中的intern方法强制2个字符串指向同一个对象
PyCharm对字符串进行了优化处理
>>> a ='abc'
>>> b='ab'+'c'
>>> c=''.join(['ab','c'])
>>> a is b
True
>>> a is c
False
>>>

b的值是程序运行之前就已经拼接完毕了
c的值是在程序运行时,通过join方法对字符串进行拼接的

>>> import sys
>>> a='abc%'
>>> b='abc%'
>>> a is b
False
>>> a = sys.intern(b)
>>> a is b
True
>>>

sys中的intern方法强制2个字符串指向同一个对象
之所以使用交互模式演示是因为,PyCharm对字符串进行了优化处理,原本不驻留的PyCharm进行了强制处理

驻留机制的优缺点

​ 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串的比较影响性能的。
​ 再需要进行字符串拼接时建议使用,str类型的join方法,而非+,因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new一个对象,效率比“+”效率高。

46、字符串的常用操作

查询方法
方法名称作用
index()查找子串第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex()查找子串最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
find()查找子串第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind()查找子串最后一次出现的位置,如果查找的子串不存在时,则返回-1
s = 'hello,hello'
print(s.index('lo'))  # 3
print(s.find('lo'))  # 3
print(s.rindex('lo'))  # 9
print(s.rfind('lo'))  # 9

# print(s.index('k'))  # ValueError: substring not found
print(s.find('k'))  # -1
字符串大小写转换
方法名称作用
upper()把字符串中所有字符都转成大写字母
lower()把字符串中所有字符都转成小写字母
swapcase()把字符串中所有大写字母转成小写字母,所有小写字母转成大写字母
capitalize()把第一个字符转成大写,把其余字符转成小写
title()把每一个单词的第一个字母转成大写,每个单词剩余的字母转成小写
# 字符串中大小写转换的方法

s = 'hello,python'
a = s.upper()  # 转换之后会产生一个新的字符串对象
print(a, id(a))  # HELLO,PYTHON 2406626132592
print(s, id(s))  # hello,python 2406626181232

b = s.lower()  # 本来就是小写,全部转换成小写也会产生一个新的字符串对象
print(b, id(b))  # hello,python 1513563026032
print(b is s)  # False

s2 = 'HelLo,pyThOn'
c = s2.swapcase()  # 大写变小写,小写变大写
print(c)  # hELlO,PYtHoN

d = s2.capitalize()  # 字符串第一个字符编程大写,其余都变成小写
print(d)  # Hello,python

e = s2.title()  # 每个单词第一个字母大写,其余小写
print(e)  # Hello,Python
字符串内容对齐操作
对象名称作用
center()居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串
ljust()左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串
rjust()右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串
zfill()右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定宽度小于字符串本身的长度,则返回字符串本身
s = 'hello,python'
print(s.center(20, '*'))  # ****hello,python****
print(s.ljust(20, '*'))  # hello,python********
print(s.ljust(10, '*'))  # hello,python     长度不够,默认返回原字符串
print(s.ljust(20))  # hello,python             参数2不写,默认返回空格

print(s.rjust(20, '*'))  # ********hello,python
print(s.rjust(20))  #         hello,python
print(s.rjust(10)) # hello,python

print(s.zfill(20))# 00000000hello,python 使用0进行填充
print('-8910'.zfill(8))# -0008910   当数字为负数的时候,0会添加到'-'后面
字符串劈分的操作
方法名称作用
split()从字符串的左边开始劈分,默认我的劈分字符为空格字符串,返回值为一个列表;通过参数sep指定劈分字符串的劈分符;通过参数maxsplit指定字符串的最大劈分次数,达到最大劈分次数,剩余的字符串单独作为一个整体
rsplit()从字符串的右边开始劈分,默认我的劈分字符为空格字符串,返回值为一个列表;通过参数sep指定劈分字符串的劈分符;通过参数maxsplit指定字符串的最大劈分次数,达到最大劈分次数,剩余的字符串单独作为一个整体
s = 'hello world Python'
lst = s.split()  # 不指定分隔符,默认为空格字符串
print(lst)  # ['hello', 'world', 'Python']
s1 = 'hello|world|Python'
print(s1.split())  # ['hello|world|Python']  当没有空格字符串的时候,就不分割
print(s1.split(sep='|'))  # ['hello', 'world', 'Python'] sep设置分隔符
print(s1.split(sep='|', maxsplit=1))  # ['hello', 'world|Python'] maxsplit设置最大分割次数
print(s1.rsplit(sep='|', maxsplit=1))  # ['hello|world', 'Python'] maxsplit设置最大分割次数
字符串的判断操作
方法名称作用
isidentifier()判断指定的字符串是否时合法的标识符
isspace()判断指定的字符串是否全部由空白字符串组成(回车、换行、水平制表符)
isalpha()判断指定的字符串是否全部由字母组成
iddecimal()判断指定的字符串是否全部由十进制的数字组成
isnumeric()判断指定的字符串是否全部由数字组成
isalnum()判断指定的字符串是否全部由字母和数字组成
s = 'hello,python'
print(s.isidentifier())  # False 有逗号,不是合法的标识符
print('hello_'.isidentifier())  # True
print('张三_'.isidentifier())  # True

print('\t'.isspace())  # True 是空白字符串

print('abc'.isalpha())  # True
print('张三'.isalpha())  # True
print('张三1'.isalpha())  # Flase

print('123'.isdecimal())  # True
print('123四'.isdecimal())  # False

print('123'.isnumeric())  # True
print('123四'.isnumeric())  # True  罗马数字也可以,也是数字

print('abc1'.isalnum())  # True
print('张三123'.isalnum())  # True
print('abc!'.isalnum())  # False

字符串操作的其他方法

功能方法名称作用
字符串替换replace()第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换之前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数
字符串的合并join()将列表或元组中的字符串合并成一个字符串
s = 'hello,Python'
print(s.replace('Python', 'java'))  # hello,java

s1 = 'hello,python,python,python'
print(s1.replace('python', 'java', 2))  # hello,java,java,python

lst = ['hello', 'java', 'python']
print(','.join(lst))  # hello,java,python

print('*'.join('Python'))  # P*y*t*h*o*n 

47、字符串的比较操作

可以使用比较运算符>,>=,<,<=,==,!=
比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,知道两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串的所有后续字符将不再被比较。

print('apple' > 'app')  # True
print('apple' > 'banana')  # False
print(ord('a'), ord("b"))  # 97 98
print(chr(97), chr(98))  # a b
print(ord('周'))  # 21608
print(chr(21608))  # 周

48、字符串的切片操作

字符串时不可变序列,不具备增删改操作,切片操作会产生性的对象。

s = 'hello.python'
s1 = s[:5]
s2 = s[6:]
print(s1)  # hello
print(s2)  # python
print(s1 + "!" + s2)  # hello!python

print('--------------切片[start:stop:step]---------------------------')

print(s[1:5:1])  # ello   左闭右开
print(s[::2])  # hlopto  默认从0开始,默认到字符串最后一个元素,步长表示间隔为2
print(s[::-1])  # nohtyp.olleh  步长为负数,从后往前;步长为正数从前往后

49、格式化字符串

为什么需要格式化字符串

格式化字符串的方式:

%作为占位符

​ %s 表示字符串
​ %i或%d表示整数
​ %f表示浮点数
​ ‘我的名字叫%s,今年%d岁了’ %(name,age)

{}作为占位符

​ ‘我的名字叫{0},今年{1},我真的叫{0}’ format(name,age)

# 第一种占位符%
name = '张三'
age = 21
print('我叫%s,今年%d岁了' % (name, age))  # 我叫张三,今年21岁了

# 第二种占位符
print('我叫{0},今年{1}岁了,我真的叫{0}'.format(name, age))  # 我叫张三,今年21岁了,我真的叫张三

# 第三种方式 f-string
print(f'我叫{name},今年{age}岁了')  # 我叫张三,今年21岁了
表示宽度和精度
print('%10d' % 99)  # 99       10表示宽度
print('hellohello')  # hellohello
print('%f' % 3.1415926)  # 3.141593
print('%.3f' % 3.1415926)  # 3.142   也用作保留几位小数,表示精度
# 同时表示宽度和精度
print('%10.3f' % 3.1415926) #      3.142
print('{0}'.format(3.1415926))  # 3.1415926
print('{0:.3}'.format(3.1415926))  # 3.14           .3表示总共保留3位数
print('{0:.3f}'.format(3.1415926))  # 3.142         .3f表示的是保留3位小数
print('{0:10.3f}'.format(3.1415926))  #      3.142         10.3f表示的是宽度为10,小数部位保留3位小数

50、字符串的编码转换

编码:将字符串转换成二进制的数据(bytes)

解码:将二进制数据转换成字符串类型

s = '天涯共此时'
# 编码
print(s.encode(encoding='GBK'))  # b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
# 在GBK这种编码格中,一个中文占两个字节
print(s.encode(encoding='UTF-8'))  # b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
# 在UTF-8这种编码格中,一个中文占三个字节

# 解码
byte = s.encode(encoding='GBK')  # 编码
print(byte.decode(encoding='GBK'))  # 解码 天涯共此时

编码跟节码要相同

第十章 水晶球不调不动 函数

51、函数的创建与调用

什么是函数

​ 函数就是执行特定任务和以完成特定功能的一段代码

为什么需要函数

​ 实现代码复用
​ 隐藏实现细节
​ 提高可维护性
​ 提高可阅读性便于调试

函数的创建

​ def 函数名 ([输入参数]) :

​ 函数体

​ [return xxx]

[]表示可有可无

def calc(a, b):
    c = a + b
    return c


result = calc(10, 20)
print(result)  # 30

52、函数的参数传递

a,b为形参,10,20为实参

位置传参

关键字传参

def calc(a, b):
    c = a + b
    return c


# 位置传参
result = calc(10, 20)
print(result)  # 30

# 关键字传参
result1 = calc(b=10, a=20)
print(result1)  # 30
可变对象跟不可变对象在函数中作为入参的区别
def fun(arg1, arg2):
    print('arg1', arg1)
    print('arg2', arg2)
    arg1 = 100
    arg2.append(10)
    print('arg1', arg1)
    print('arg2', arg2)


n1 = 11
n2 = [22, 33, 44]
print(n1)
print(n2)
print('-------------------------')
fun(n1, n2)
print(n1)
print(n2)
结果
11
[22, 33, 44]
-------------------------
arg1 11
arg2 [22, 33, 44]
arg1 100
arg2 [22, 33, 44, 10]
11
[22, 33, 44, 10]

在函数的调用过程中,进行参数的传递
如果是不可变对象,在函数体内的修改不会影响实际实参的值
如果是可变对象,在函数体内的修改会影响到实参的值

53、函数的返回值

函数返回多个值时,结果为元组

print(bool(1))  # True


def fun(num):
    odd = []
    even = []
    for i in num:
        if i % 2:
            odd.append(i)
        else:
            even.append(i)
    return odd, even


print(fun([10, 29, 34, 23, 44, 53, 55]))  # ([29, 23, 53, 55], [10, 34, 44]) 返回值为一个元组

函数的返回值
如果函数没有返回值【函数执行完成之后,不需要给调用者返回数据】return可以省略不写
函数的返回值,如果是1个,直接返回原类型
函数的返回值,如果是多个,返回的结果为元组

函数在定义时,是否需要返回值,视情况而定

54、函数的参数定义

函数定义默认值参数

​ 函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参

def fun(a, b=10):  # 10为b的默认值
    print(a, b)


fun(100)  # 100 10    当参数只有一个的时候,b会用默认值
fun(20, 30)  # 20 30  当参数有两个的时候,b会使用入参的值

print('hello')  # end 默认为\n 换行
print('hello', end='\t')
print('world')
可变参数 参数数量可变
个数可变的位置形参

​ 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
​ 使用定义个数可变的位置形参
入参在函数中显示为一个元组

个数可变的位置参数在函数中只能有一个

def fun(*args):
    print(args)
    print(args[0])


fun(10)
fun(10, 30)
fun(30, 405, 50)

'''
(10,)
10
(10, 30)
10
(30, 405, 50)
30
'''

'''
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
'''
个数可变的关键字形参

​ 定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
​ 使用两个✳✳定义个数可变的关键字形参
入参在函数中显示为一个字典

个数可变的关键字参数在函数中只能有一个

def fun1(**args):
    print(args)


fun1(a=10)  # {'a': 10}
fun1(a=20, b=30, c=40)  # {'a': 20, 'b': 30, 'c': 40}
def fun(*args1, **args2):
    pass


'''def fun(**args, *args1):
    pass
    
    在一个函数定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参时
    要求:
        个数可变的位置形参必须放在个数可变的关键字形参之前!否则报错
    '''
函数调用
def fun(a, b, c):
    print('a=', a)
    print('b=', b)
    print('c=', c)


# 函数的调用
fun(10, 20, 30)  # 函数调用时的位置传参
lst = [11, 22, 33]
fun(*lst)  # 在函数调用时,将列表中的每一个元素都转换为位置实参传入
print('-------------------------------------')
fun(a=100, b=200, c=300)  # 函数调用时的关键字传参
dic = {'a': 111, 'b': 222, 'c': 333}
fun(**dic)  # 在函数调用时,将字典中的每一个元素都转为关键字实参传入   注意,字典中的key必须与函数中的形参名一致
函数定义
def fun(a, b=10):  # b在函数的定义处,所以b是形参,而且进行了赋值,所以b称为默认值形参
    print(a)
    print(b)


def fun2(*args):  # 个数可变的位置形参
    print(args)


def fun3(**args):  # 关键字可变的关键字形参
    print(args)


fun2(10, 20, 30, 40)
fun3(a=11, b=22, c=33, d=44, e=55)


def fun4(a, b, c, d):
    print('a', a)
    print('b', b)
    print('c', c)
    print('d', d)


# 调用fun4函数
fun4(10, 20, 30, 40)  # 位置实参传递
fun4(a=11, b=22, c=33, d=44)  # 关键字实参传递
fun4(11, 22, c=33, d=44)  # a,b采用位置实参传递,c,d采用关键字实参传递


'''需求cd只能采用关键字实参传递'''
def fun5(a, b, *, c, d):  # 从*之后的参数,在函数调用时,只能采用关键字参数传递
    pass

'''函数定义时形参的顺序问题'''
def fun6(a,b,*,c,d,**args):
    pass
def fun7(*args,**args1):
    pass
def fun8(a,b=10,*args,**args1):
    pass

55、变量的作用域

程序代码能访问该变量的区域
根据变量的有效范围可分为:
局部变量:

​ 在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成为全局变量
​ 全局变量:

​ 函数体外定义的变量,可作用于函数内外

def fun(a, b):
    c = a + b  # c,就称为局部变量,以为c是在函数体内进行定义的变量,a,b为函数的形参,作用范围也是函数内部,相当于局部变量
    print(c)


# print(c)
# print(a) 报错,超出了作用域

name = '周'  # nam的作用范围为函数内部和外部都可以使用-->称为全局变量
print(name)
def fun1():
    print(name)
fun1()


def fun2():
    global age  # 函数内定义的变量,使用global声明,该变量变为全局变量
    age = 10
    print(age)
fun2()
print(age)

56、函数递归

一个函数的函数体调用该函数本身,就成为递归函数

递归的组成部分
递归调用与递归终止条件

递归的调用过程
每递归调用一次函数,都会在栈内存分配一个栈帧
每执行完一次函数,才会释放相应的内存空间

递归的优缺点
缺点:占用内存多,效率低
优点:思路和代码简单

# 递归函数
def fun(num):
    if num >= 1:
        return num * fun(num - 1)
    else:
        return 1
    
print(fun(6))  # 720

斐波那契数列:位置上的数等于前两个位置上的数之和

# 斐波那契数列
def fun(n):
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return fun(n - 1) + fun(n - 2)


print(fun(6))  # 8

print('---------------------------')
# 输出前六位数字
for i in range(1, 7):
    print(fun(i))

第十一章 全民来找茬 bug异常

57、bug的由来及分类

bug分类之粗心
age = input("请输入年龄:")
print(type(age))
if int(age) >= 18:
    print('成年人做事要负法律责任了')

i = 0
while i < 10:
    print(i)
    i += 1

索引越界IndexError

lst=[11,22,33,44]
print(lst[4])   索引从0到3越界了

append()方法使用不熟练

lst = []
lst=append('a','b','c')  append为list的函数,是.出来的,而且append每次只能添加一个元素
print(lst)
bug分类之思路不清晰
bug分类之用户错误操作或例外情况

例如求两个数的商,用户可能输入的不是数字或者除数输入的是0

解决方法:利用python提供的异常处理机制,在异常出现时及时捕获,然后内部消化,以达到让程序继续运行的目的

try…except…结构

try:

​ 可能出现异常的代码

except 异常类型1:

​ 报错后执行的代码

except 异常类型2:

​ 报错后执行的代码

捕获异常的顺序按照先子类再父类的顺序,为避免遗漏可能出现异常,可以在最后增加最大的异常

最大的异常时BaseException

try…except…else结构

如果程序try中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块

try:
    a = int(input('请输入第一个整数:'))
    b = int(input('请输入第二个整数:'))
    result = a / b
except BaseException as e:
    print('出错了', e)  # 出错了 invalid literal for int() with base 10: 'a'
else:
    print(type(result))  # float
    print('计算结果为:', result)  # 5.0
try…except…else…finally…结构

无论是否出异常,finally块中的代码都会被执行,通常用来释放try中申请的资源

try:
    a = int(input('请输入第一个整数:'))
    b = int(input('请输入第二个整数:'))
    result = a / b
except BaseException as e:  # try出异常执行此块
    print('出错了', e)  # 出错了 invalid literal for int() with base 10: 'a'
else:  # try不出异常执行此块
    print(type(result))  # float
    print('计算结果为:', result)  # 5.0
finally:  # 不论是否出异常,finally块中的代码必定被执行
    print('谢谢您的使用!')
常见的异常类型
序号异常类型描述
1ZeroDivisionError除(或者取模)零(所有数据类型)
2IndexError序列中没有此索引(index)
3KeyError映射没有这个键
4NameError未申明/初始化对象(没有属性)
5SyntaxErrorPython语法错误
6ValueError传入无效的参数
traceback模块

使用traceback模块打印异常信息

import traceback

try:
    print('1.---------------------')
    num = 1 / 0
except:
    traceback.print_exc()  # ZeroDivisionError: division by zero

58、Pycharm中的程序调试

第十二章 对象 类

59、两大编程思想

面向过程:线性思维方式去解决问题,第一步干啥,第二步干啥

面向对象:不需要关注过程

60、类与对象

Python中的一切皆对象

61、类的创建

类的组成

类属性
实例方法
静态方法
类方法
class Student:  # 类名由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_pace = '吉林'  # 直接写在类里面的变量,称为类属性

    # 初始化方法
    def __init__(self, name, age):
        self.name = name  # self.name称为实体属性,进行了一次赋值操作,将局部变量name的值赋值给实体属性
        self.age = age

    # 实例方法   默认由self
    def eat(self):
        print('学生在吃饭。。。')

    # 静态方法
    @staticmethod
    def method():
        print('我使用了staticmethod进行修饰,所以我是静态方法,静态方法当中是不允许写self')

    # 类方法
    @classmethod
    def cm(cls):
        print('我是类方法,因为使用了classmethod进行修饰')


'''在类之外定义的称为函数,在类之内定义的称为方法'''
def drink():
    print('喝水')

62、对象的创建

对象的创建称为类的实例化

语法:实例名=类名()

stu1 = Student('张三', 20)
stu1.eat()# 对象名.方法名()
print(stu1.name) 
print(stu1.age)

print('------------------------------------')
Student.eat(stu1)  # 类名.方法名(类的对象) stu1.eat()的功能相同
Student.method()

63、类属性、类方法、静态方法

类属性:类中方法外的变量称为属性,被该类的所有对象所共享
类方法:使用@classMethod修饰分方法,使用类名直接访问的方法
静态方法:使用@staticMethod修饰的方法,使用类名直接访问的方法

# 类属性的使用方式
print(Student.native_pace)  # 吉林
stu1 = Student('张三', 20)
stu2 = Student('李四', 21)
print(stu1.native_pace)  # 吉林
print(stu2.native_pace)  # 吉林
Student.native_pace = '天津'
print(stu1.native_pace)  # 天津
print(stu2.native_pace)  # 天津

'''类属性时属于类的,类属性时共享的,类对象通过类指针找到类的类属性'''

# 类方法的使用方式
Student.cm()  # 我是类方法,因为使用了classmethod进行修饰

# 静态方法的使用方式
Student.method()  # 我使用了staticmethod进行修饰,所以我是静态方法,静态方法当中是不允许写self

64、动态绑定属性和方法

python时动态语言,在创建对象之后,可以动态绑定属性和方法

stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
print('-----------为stu2动态绑定性别类型-------------')
stu2.gender = '女'  # 动态绑定性别属性
print(stu1.name, stu1.age)  # 张三 20
print(stu2.name, stu2.age, stu2.gender)  # 李四 30 女  性别属性时stu2特有的属性


print('-----------为stu1动态绑定性别类型-------------')
def show():
    print('定义在类之外,称为函数')


stu1.show = show  # 动态绑定方法
stu1.show()  # 定义在类之外,称为函数

第十三章 对象

65、面向对象的三大特征

封装:提高程序的安全性

​ 在python中没有专门的修饰符用于属性的私有,如果不希望该属性在类对象外部被访问,前边使用两个”_“修饰

class Student:
    def __init__(self, name, age):
        self.__age = age  # 年龄不希望在类的外部去使用,所以加了两个_
        self.name = name

    def show(self):
        print(self.name, self.__age)


stu = Student('张三', 20)
stu.show()
print(stu.name)# 张三
# print(stu.__age) # AttributeError  属性错误   在类的外部无法访问到
# print(dir(stu))
print(stu._Student__age)  # 在类的外部可以通过"_类名__属性名"的方式访问   20
继承:提高代码的复用性

class 子类类名(父类1,父类2,…):

​ pass

如果一个类没有继承任何类,则默认继承Object类

class Person:  # 什么都不写,默认继承object
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print(self.name, self.age)


class Student(Person):
    def __init__(self, name, age, stu_no):
        super().__init__(name, age)
        self.stu_no = stu_no


class Teacher(Person):
    def __init__(self, name, age, teacherofyear):
        super().__init__(name, age)
        self.teacherofyear = teacherofyear


stu = Student('张三', 20, '1001')
tea = Teacher('李四', 34, 10)
tea.info()
stu.info()

python支持多继承

class A:
    pass


class B:
    pass


class C(A, B):
    pass

定义子类时,必须在其构造函数中调用父类的构造函数

方法重写
class Person:  # 什么都不写,默认继承object
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print(self.name, self.age)


class Student(Person):
    def __init__(self, name, age, stu_no):
        super().__init__(name, age)
        self.stu_no = stu_no

    def info(self):
        super().info()
        print(self.stu_no)


class Teacher(Person):
    def __init__(self, name, age, teacherofyear):
        super().__init__(name, age)
        self.teacherofyear = teacherofyear

    def info(self):
        super().info()
        print('教龄', self.teacherofyear)


stu = Student('张三', 20, '1001')
tea = Teacher('李四', 34, 10)
tea.info()
print('-------------------')
stu.info()
object类
object类是所有类的父类,因此所有类都有object类的属性和方法。
内置的函数dir()可以查看指定对象的所有属性。
Object有一个_str_()方法,用于返回一个对于”对象的描述“,对应于内置函数str()经常用于print()方法,帮助我们查看对象的信息,所以我们经常会对_str()_方法重写。
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return '我的名字是{0},今年{1}岁了'.format(self.name, self.age)


stu = Student('张三', 20)
print(dir(stu))
print(stu)  # 默认会调用_str()_方法
print(type(stu))
多态:提高程序的可扩展性和可维护性

多态就是具有多种形态,指的是:即便不知道一个变量所引用的对象到底是什么类型,任然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。

静态语言和动态语言关于多态的区别

静态语言实现多态的三个必要条件:(java多态必须有这三个要素)
继承
方法重写
父类型的引用指向子类型的对象

动态语言的多态崇尚”鸭子类型“,当看到一只鸟走起来像鸭子、游泳像鸭子、走起来也像鸭子,那么这只鸟就可以被称为鸭子,在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。(python多态只关心是否有这个方法)

# 开发人员: 周  伟
# 开发时间: 2021/11/24 9:21

class Animal(object):
    def eat(self):
        print('动物会吃')


class Dog(Animal):
    def eat(self):
        print('狗吃骨头')


class Cat(Animal):
    def eat(self):
        print('猫吃鱼')


class Person:
    def eat(self):
        print('人吃五谷杂粮')


# 定义函数
def fun(obj):
    obj.eat()


# 调用函数
fun(Cat())
fun(Dog())
fun(Animal())
print('------------------')
fun(Person())
特殊属性和特殊方法
特殊属性: __dict__  获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
	__len__()通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
	__add__()通过重写__add__()方法,可以使自定义对象具有“+”功能
	__new__()用于创建对象
	__init__()对创建的对象进行初始化
class A:
    pass
class B:
    pass
class C(A, B):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print('吃')
# 创建C类的对象
x = C('Jack', 20)
print(x.__dict__)  # 实例对象,可以获取实例对象的属性 {'name': 'Jack', 'age': 20}
print(
    C.__dict__)  # 类对象,可以获取类对象有哪些方法{'__module__': '__main__', '__init__': <function C.__init__ at 0x00000164B89FEEE0>, 'eat': <function C.eat at 0x00000164B8A00430>, '__doc__': None}

print('----------------')
print(x.__class__)  # <class '__main__.C'> 输出了对象所属的类
print(C.__bases__)  # (<class '__main__.A'>, <class '__main__.B'>) 输出了类的父类型元组
print(C.__base__)  # <class '__main__.A'> 输出第一个父类型,按父类型写的顺序排的,谁写在前面输出谁
print(C.__mro__)  # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)  显示所有继承的类,查看类的继承结构
print(A.__subclasses__())  # [<class '__main__.C'>] 查看有哪些子类列表

add和len方法是使用:

class Student:
    def __init__(self, name):
        self.name = name

    def __add__(self, other):
        return self.name + other.name

    def __len__(self):
        return len(self.name)


stu1 = Student('张三')
stu2 = Student('李四')

s = stu1 + stu2  # 张三李四 实现了两个对象的加法运算(因为在Student中编写了__add__()特殊方法)
print(s)
print('------------------------')
lst = [11, 22, 33, 44]
print(len(lst))  # len是内置函数len 4
print(lst.__len__())  # 4
print(len(stu1))  # 2

new和init方法的作用

class Person(object):
    def __new__(cls, *args, **kwargs):
        print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
        obj = super().__new__(cls)
        print('创建的对象的id为:{0}'.format(id(obj)))
        return obj

    def __init__(self, name, age):
        print('__init__方法被调用了,self的id为{0}'.format(id(self)))
        self.name = name
        self.age = age


print('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))

# 床架Person类的实例对象
p1 = Person('张三', 20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))
object这个类对象的id为:140724580961792
Person这个类对象的id为:1638837642336
__new__被调用执行了,cls的id值为1638837642336
创建的对象的id为:1638839062288
__init__方法被调用了,self的id为1638839062288
p1这个Person类的实例对象的id:1638839062288
类的浅拷贝与深拷贝

变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象
浅拷贝:python拷贝一般都是浅拷贝,拷贝是,对象包含的子对象内容不拷贝,
因此,原对象与拷贝对象引用同一个子对象
深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,原对象和拷贝对象的子对象也不相同

class Cpu:
    pass
class Disk:
    pass
class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk
# 变量的赋值
cpu1 = Cpu()
cpu2 = cpu1
print(cpu1, id(cpu1))  # <__main__.Cpu object at 0x0000014B5D957FD0> 3036854452176
print(cpu2, id(cpu2))  # <__main__.Cpu object at 0x0000014B5D957FD0> 3036854452176
# cpu1跟cpu2指向同一个对象

print('-------------------')
# 类的浅拷贝
disk = Disk()
computer = Computer(cpu1, disk)  # 创建一个计算机类的对象

import copy

computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
# 此时两个computer的对象是不同的,但是其属性cpu跟disk确实指向同一个内存地址,是相同的,这就是浅拷贝

print('-----------------------')
computer3 = copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)
# 此时两个conputer的对象是不相同的,cpu跟disk两个属性也完成了拷贝
<__main__.Cpu object at 0x000001D432C08FD0> 2010896175056
<__main__.Cpu object at 0x000001D432C08FD0> 2010896175056
-------------------
<__main__.Computer object at 0x000001D432C08E50> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
<__main__.Computer object at 0x000001D432C08D60> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
-----------------------
<__main__.Computer object at 0x000001D432C08E50> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
<__main__.Computer object at 0x000001D432C08790> <__main__.Cpu object at 0x000001D432C08430> <__main__.Disk object at 0x000001D432C08460>

第十四章 百宝箱 模块和包

66、模块

模块英文为modules
函数与模块的关系
一个模块中可以包含多个函数
python中以一个扩展名为.py的文件就是一个模块
使用模块的好处
方便其他程序和脚本的导入并使用
避免函数名和变量名的冲突
提高代码的可维护性
提高代码的可重复性

创建模块

新建一个.py文件,名称尽量不要与python自带的标准模块名称相同,要见名知意

导入模块

import 模块名称 [as 别名]

import math  # 关于数学运算

print(id(math))
print(type(math))
print(math)
print(math.pi)  # 3.141592653589793
print('-----------------')
print(dir(math))
print(math.pow(2, 3))  # 8.0 2的3次方
print(math.ceil(9.001))  # 10 向上取整
print(math.floor(9.999))  # 9 向下取整

from 模块名称 import 函数/变量/类

from math import pi # 单独导入某个模块中的特定的函数/变量/类

print(pi)  # 3.141592653589793
以主程序形式运行
在每个模块的定义中都包括一个记录模块名的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他模块中执行,那么他可能在解释器的顶级模块中执行,顶级模块的__name__变量的值为__main__
if __name__ == '__main__':
	pass

意思是直接运行当前.py文件本身的时候,才会执行pass,而当作为模块引入到变得.py文件,运行别的.py文件时,pass中的代码不会执行
如果不适用if判断,则会导致pass中的程序,在别的.py文件执行的过程中也会执行

python中的包
包时一个分层次的结构,它将一组功能相近的模块组织在一个目录下
作用:
	代码规范
	避免模块冲突
包与目录的区别
	包含__init__.py文件的目录成为包
	目录通常不包含__init__.py文件
包的导入
	import 包名.模块名
import package
import calc
# 使用import方式进行导入时,只能跟包名或者模块名

from package import module_A
from package.module_A import a
# 使用from...import可以导入包,模块,函数,变量
python中常用的内置模块
模块名描述
sys与python解释器及其环境操作相关的标准库
time提供与时间相关的各种函数的标准库
os提供了访问操作系统服务功能的标准库
calendar提供了与日期相关的各种函数的标准库
urllib用于读取来自网上(服务器)数据的标准库
json用于使用JSON序列化和反序列化对象
re用于在字符串中执行正则表达式匹配和替换
math提供标准算数运算函数的标准库
decimal用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能
import sys
import time
import os  # 操作系统服务功能的标准库   文件存储啥的
import calendar  # 获取日期
import urllib.request  # 爬虫需要使用到
import json  # 序列化和反序列化 爬虫也会用到
import re  # 正则表达式 爬虫也会用到
import math
import decimal  # 浮点数进行运算的时候会出行不准确的情况
import logging # 日志功能

print(sys.getsizeof(24))  # 28
print(sys.getsizeof(45))  # 28
print(sys.getsizeof(True))  # 28
print(sys.getsizeof(False))  # 24

print(time.time())  # 1637746651.9063413
print(time.localtime(
    time.time()))  # time.struct_time(tm_year=2021, tm_mon=11, tm_mday=24, tm_hour=17, tm_min=37, tm_sec=31, tm_wday=2, tm_yday=328, tm_isdst=0)

print(urllib.request.urlopen('http://www.baidu.com').read())  # 将百度这个地址中所有数据读取回来
print(math.pi)  # 3.141592653589793
第三方模块的安装以及使用

第三方模块在线安装方式: pip install 模块名 在doc命令中使用

第三方模块使用:import 模块名

import schedule
import time


def job():
    print('哈哈')


schedule.every(3).seconds.do(job)# 设置定时任务规则
while True:
    schedule.run_pending()# 启动定时任务
    time.sleep(1)

第十五章 大宝藏 编码格式、文件读写原理、with语句、目录操作

67、常见的编码格式

python的解释器使用的shiunicode(没存)

.py文件在磁盘上使用UTF-8存储(外存)

utf-8相当于unicode的具体实现

设置编码格式:在模块第一行添加# encoding=gbk

# encoding=gbk
print('你好中国')

不同的编码格式会导致文件大小不一样

68、文件的读写原理

文件的读写俗称“IO操作”input,output
文件独写操作流程
python操作文件–>打开或者新建文件–>读、写文件–>关闭资源
读是指从别的地方读入内存当中
写是指从内存中写道磁盘当中

读入写出

file = open(filename [,mode,encoding])
解释:
file 表示被创建的文件对象
open 创建文件对象的函数
filename 要创建或者打开的文件的名称
mode 打开模式默认为只读
encoding 默认文本文件中字符的编写格式为gbk

读取磁盘文件的内容

file = open('a.txt', 'r')
print(file.readlines())
file.close()

69、常用的文件打开模式

文件的类型

按文件中数据的组织形式,文件分为以下两大类
文本文件:存储的普通“字符”文本,默认为unicode字符集,可以使用记事本程序打开
二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件文件打开,举例:MP3音频文件,jpg图片文件,doc文档等

打开模式描述
r以只读模式打开,文件的指针将会放在文件的开头
w以只写模式打开,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾
b以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb或者wb
+以独写方式打开文件,不能单独使用,需要与其他模式一起使用,a+
file = open('a.txt', 'r')
print(file.readlines())
file.close()

file = open('b.txt', 'w')
file.write('Python')
file.close()

file = open('b.txt', 'a')
file.write('Python')
file.close()

src_file = open('copy.gif', 'rb')
target_file = open('copylogo.gif', 'wb')
target_file.write(src_file.read())
src_file.close()
target_file.close()

70、文件对象常用的方法

方法名说明
read([size])从文件中读取size个字节或字符的内容返回。若省略[size]则读取到文件末尾,即一次读取文件所有的内容
readline()从文本文件中读取一行内容
readlines()把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str)将字符串str内容写入文件
writelines(s_list)将字符串列表s_list写入文本文件,不添加换行符
seek(offset[,whence])把文件指针移动到新的位置,offset便是相对于whence的位置:
offset:为正往结束方向移动,为负往开始方向移动
whence:不同的值代表不同的含义
0:表示从文件头开始计算
1:表示从当前位置开始计算
2:表示从文件尾开始计算
tell()返回文件指针的当前位置
flush()把缓冲区的内容写入文件,但不关闭文件
close()把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源
file = open('a.txt', 'r')
print(file.read())# 中国
                  # 美丽
print(file.readline())# 中国
print(file.readlines())# ['中国\n', '美丽']
file.close()
file = open('c.txt', 'a')
# print(file.read())# 中国
#                   # 美丽
# print(file.readline())# 中国
# print(file.readlines())# ['中国\n', '美丽']
# file.write('hello')# hello
lst = ['java', 'go', 'python']
file.writelines(lst)  # hellojavagopython
file.close()
file = open('c.txt', 'r')  # hellojavagopython

file.seek(2)  # 中文占两个字节   文件指针往后移动两位
print(file.read())  # llojavagopython
print(file.tell())  # 17  获取文件指针的位置
file.close()

71、with语句(上下文管理器)

with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的

with open('a.txt','rb') as src_file :
	with语句体
with open('a.txt', 'r') as file:
    print(file.read())
print(type(open('a.txt', 'r')))  # <class '_io.TextIOWrapper'>
'''
MvContentMgr类实现了特殊方法__enter__(),__exit__()称该类对象遵守了上下文管理器协议
该类对象的实例对象,称为上下文管理器
'''
class MvContentMgr:
    def __enter__(self):
        print('enter方法被调用执行了')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit方法被调用执行了')

    def show(self):
        print('show方法被调用执行了')


with MvContentMgr() as file:  # 相当于file=MvContentMgr()
    file.show()  # 不论是否发生异常,只要跳出with块,就会执行__exit__()方法
# enter方法被调用执行了
# show方法被调用执行了
# exit方法被调用执行了

72、目录操作

os模块是python内置的与操作系统功能和文件相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样
os模块与os.path模块用于对目录或文件进行操作

# os模块与操作系统相关的模块,可以调用系统文件
import os
# 调用操作系统的功能
os.system('notepad.exe') # 打开记事本
os.system('calc.exe')# 打开计算机
# 直接调用可执行文件
os.startfile('C:\\Program Files\\HeidiSQL\\heidisql.exe')
os模块操作目录相关函数
函数说明
getcwd()返回当前的工作目录路径
listdir(path)返回指定路径下的文件和目录信息
mkdir(path[,mode])创建目录
makedirs(path1/path2…[,mode])创建多级目录
rmdir(path)删除目录
removedirs(path1/path2…)删除多级目录
chdir(path)将path设置为当前工作目录
import os

print(os.getcwd())
print(os.listdir('..\\chap15'))

os.mkdir('newdir2')# 创建目录
os.makedirs('A/B/C')  # 创建多级目录   A目录下有B目录,B目录下有C目录
os.rmdir('newdir2')  # 删除目录
os.removedirs('A/B/C')  # 移除多级目录
os.chdir('../')  # 将上一级目录设置问工作目录
os.path模块操作目录相关函数
函数说明
abspath(path)用于获取文件或者目录的绝对路径
exists(path)用于判断文件或者目录是否存在,如果存在返回True,不存在返回False
join(path,name)将目录与文件名拼接起来
splitext()分离文件名与扩展名
basename(path)从一个目录中提取文件名
dirname(path)从一个路径中提取文件路径,不包括文件名(文件所在目录的路径)
isdir(path)用于判断是否为路径
import os.path

print(os.path.abspath('demo13.py'))  # 获取文件或目录的绝对路径
print(os.path.exists('demo17.py'), os.path.exists('demo18.py'))  # True False
print(os.path.join('E:\\python', 'demo12.py'))  # E:\python\demo12.py  拼接起来
print(os.path.split('E:\\python\\chap15\\demo17.py'))  # ('E:\\python\\chap15', 'demo17.py') 拆分最后一个文件
print(os.path.splitext('demo17.py'))  # ('demo17', '.py') 拆分文件与后缀名
print(os.path.basename('E:\\python\\chap15\\demo17.py'))  # demo17.py  提取一个路径中的文件名(含后缀)
print(os.path.dirname('E:\\python\\chap15\\demo17.py'))  # E:\python\chap15  提取文件或者目录所在的路径
print(os.path.isdir('E:\\python\\chap15\\demo17.py'))  # False 不是目录,因为结尾是文件
# 列出指定目录下所有的以.py结尾文件
import os

lst = os.listdir()  # 当前工作目录下的目录和文件信息

lst1 = []
for file in lst:
    if file.endswith('.py'):
        lst1.append(file)
    # str = os.path.splitext(file)[1]
    # if str == '.py':
    #     lst1.append(file)
print(lst1)

遍历某个文件夹下所有的子目录和文件,以及子目录下的内容

import os

path = os.getcwd()
lst_file = os.walk(path)
print(lst_file)
for dirpath, dirname, filename in lst_file:
    '''print(dirpath)  # 当前的路径 列表
    print(dirname)  # 当前目录下有哪些目录   列表
    print(filename)  # 当前目录下有哪些文件   列表
    print('------------------------')'''
    for dir in dirname:
        print(os.path.join(dirpath,dir))
    for file in filename:
        print(os.path.join(dirpath,file))
    print('--------------------------------------------')

学生信息管理系统

1、需求分析

添加学生信息及成绩信息
将学生信息保存到文件中
修改和删除学生信息
查询学生信息
根据学生成绩进行排序
统计学生的总分

2、系统设计

录入、查找、删除、修改学生信息
学生成绩排名
总人数统计
显示全部学生信息

匿名函数 lambda 自定义名称:函数

类似于jdk8新特性中的表达式

将字符串转换成dict字典

d = dict(eval(字符串))

项目打包

安装第三方模块
在线安装
pip install PyInstaller

执行打包操作
pyinstaller -F 文件的绝对路径
-F的意思是只生成一个扩展名为exe的可执行文件

注意事项:

变量名等,两个单词之间_连接,例如book_name

zip使用
list1=[]
list2=[]
for s,a in zip(list1,list2):
print(s.a)

pycharm的功能设置输出内容的颜色
\033[显示方式;字体颜色;背景颜色m
print(‘\003[0;35m你好吗’) # 你好吗

def fun():
    num = 4
    print(num, '的二进制数为', bin(num))
    print(str(num) + '的二进制数为' + str(bin(num)))
    print('%s的二进制数为%s' % (num, bin(num)))
    print('{0}的二进制数为{1}'.format(num, bin(num)))
    print(f'{num}的二进制数为{bin(num)}')
    print(f'{num}的八进制数为{oct(num)}')
    print(f'{num}的十六进制数为{hex(num)}')
    
if __name__ == '__main__':
    while True:
        try:
            fun()
            break
        except:
            print('只能输入整数!!!')

判断字符串是否都是数字str.isdigit()

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值