变量和常量

变量

什么是变量

变量: 定义世间万物变化的状态

IPO

I —> input —> 输入(变量)

P —> Process —> 处理

O —> Output —> 输出

变量的组成

  1. 变量名:具有描述意义; 接受变量值
  2. 赋值符号:赋值,把变量值传给变量名
  3. 变量值:具体的值

变量名的规范

  1. 变量名必须要有意义
  2. 变量名由数字、字母、下划线组成,不能以数字开头
  3. 不能以关键字命名
1
2
# 关键字
['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']

定义变量名的两种方式

  • 下划线(python推荐使用)
1
neo_of_name = 'neo'
  • 驼峰体
1
NeoOfName = 'neo'

变量的三种打印形式

1
2
3
4
5
6
7
8
9
age = 20
# 打印值
print(age)

# 打印内存地址
print(id(age))

# 打印数据类型
print(type(age))

常量

常量是指不变化的量(变量名大写)

这个不变是约定俗成的

1
2
AGE = 19
AGE = AGE + 1 # 这样做就很沙雕了

注释

学任何一门编程语言一定先学注释,要养成给代码注释的好习惯。不然,一段时间过去了,自己写的代码都看不懂了。

单行注释

1
2
# 打印12
# print(12)
  • 解释代码什么意思
  • 让后面的代码失效

多行注释

用三单引号或三双引号

1
2
3
4
5
6
7
'''
写什么东西呢
'''

"""
随便写写
"""

相当于定义了一个变量不使用

python内存管理

变量存哪了

当我们在test.py文件里定义一个变量x = 10,单纯这样写只是几个字符而已,只有当python解释器运行时,才有变量这个意义。这个变量的概念是python解释器提供的。

变量在计算机内存里开辟一个小空间,小空间内存放变量值10,然后内存给这个小空间一个变量名x,x指向10。

python垃圾回收机制

1
2
x = 10
x = 11

变量在内存开辟一个小空间,小空间内存放变量值10,变量名x指向10。加上一段代码x = 11,内存会重新开辟一个空间存放11,然后x会指向11,之前x指向10的连接会断掉。这样10就成了垃圾,python会自动处理这个垃圾,释放10的内存。

1
2
3
name1 = 'rese'
name2 = name1
name1 = 'neo'

引用计数

引用计数针对的是变量值, 变量值的引用次数

1
2
3
x = 1000   # 1000的引用次数为1
y = 1000 # 1000的引用次数为2
del x # del删除x,1000的引用次数为1

当一个变量值的引用计数为0时,会触发垃圾回收机制,之前的值会被回收

小整数池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> x = 10
>>> id(10)
140704061711472
>>> y = x
>>> id(y)
140704061711472
>>> z = 10
>>> id(z)
140704061711472 # 内存地址

>>> x = 1000
>>> id(x)
1619602196368 #
>>> x = 1000
>>> id(x)
1619602196496 # 这里内存地址与之前的不同

python实现int的时候有个小整数池,这是为了避免因创建相同的值而申请重复的内存空间带来的效率问题。

python解释器会自动定义[-5, 256]之间的 整数池,这是在内存中写死的。这个范围内的整数被全局调用时,永远不会触发垃圾回收机制。

在pycharm中,这个整数范围是扩大的,它优化了。

基本数据类型

什么是数据类型

数据类型对变量值做了分类,分成了不同类别

数字类型

整型

作用:描述年龄/id号

定义方式:

1
2
3
age = 21

age = int(21)

使用方法:

1
2
3
4
5
6
7
8
9
10
x = 2
y = 1

print(x + y) # 加
print(x - y) # 减
print(x * y) # 乘
print(x / y) # 除
print(x % y) # 取余
print(x // y) # 取整
print(x ** y) # 幂运算

当你需要使用如sin/cos/tan等函数时,怎么办呢?别担心,有方法

使用cmath模块

1
2
import cmath
print(cmath.sin(10))

浮点型

作用:描述薪资

定义方式:

1
2
salary = 3.2
salary = float(3) # 3.0

使用方法:与int整型类似

逻辑比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> x = 1
>>> y = 2
>>> print(x > y)
False
>>> print(x >= y)
False
>>> print(x < y)
True
>>> print(x <= 1)
True
>>> print(x != y)
True
>>> print(x == y)
False

字符串

作用:

描述姓名/性别

定义方式:

1
2
3
name = 'cwz'

name = "cwz's name"

使用方法:

1
2
3
4
5
6
7
str1 = 'neo'
str2 = 'zen'
print(str1 + ' ' + str2)
# 打印结果:neo zen

print(str2 * 10)
# 打印结果:zenzenzenzenzenzenzenzenzenzen

列表

作用

存储多个元素,可以描述一个人的爱好

定义方式

[]内 多个元素用逗号隔开,元素可以是任意数据类型

1
2
3
4
lt1 = [1,2,3,4,5]

s_list = list('abcdef')
print(s_list) # ['a', 'b', 'c', 'd', 'e', 'f']

使用方法

索引取值

1
2
3
4
lt = [1,2,3,'neo',[666,120]]
print(lt[1]) # 2
print(lt[3]) # neo
print(lt[4][0]) # 666

字典

作用

存储多个值,但是每个值都有描述信息

定义方式

{}内用逗号隔开多个元素,键值对存储数据,key(用字符串):value(可以是任意数据类型)

1
dic = {'name':'cwz', 'age': 20}

使用方法

字典没有索引

1
2
dic = {'name':'cwz', 'age': 20}
print(dic['name']) # cwz

布尔类型

作用

用于判断条件结果, 布尔类型只有两个值,True / False

定义

True、False通常情况不会直接引用,需要使用逻辑运算得到结果

使用方法

条件成立为True,不成立为False

1
2
print(1 > 2)   # False
print(1 < 2) # True

所有数据类型都自带布尔值,除了None / 0 / 空字符串 / 空列表 / 空字典 / False 的布尔值为False,其余为True。

元组

作用

元组可以看成只可取不可修改的列表,元组一创建就被写死了

定义方式

()内用逗号隔开多个元素(可以为任意数据类型)

1
2
3
4
5
6
tup = tuple((1, 2, 3))
print(tup, type(tup))

# 如果元组只有一个元素,必须得加逗号
tup1 = (1,)
print(tup1, type(tup1))

集合

作用

进行 交集 / 并集 / 补集等运算,可以去重,但是集合内元素是乱序的

定义方式

{}内以逗号隔开多个元素(不能可为变数据类型)

1
2
3
s = {'a', 'a', 'a', 'a', 1, 'v', 2, 2, 'c', 3, 3, 4, 5, 6}  # 对于数字而言,不会乱序;但是对于其他,就乱序
print(s)
# {1, 2, 'a', 3, 4, 5, 6, 'v', 'c'}

花式赋值,解压缩、用户交互,格式化输出

花式赋值

链式赋值

1
2
3
4
5
6
7
8
9
10
>>> a = b =c =10
>>> a
10
>>> a
10
>>> c
10
>>> b
10
>>>

交叉赋值

1
2
3
4
5
6
7
8
>>> x = 10
>>> y = 20
>>> x, y = y, x
>>> x
20
>>> y
10
>>>

解压缩

只针对2-3个元素容器类型的解压

1
2
3
4
5
6
7
8
9
10
a, b, c = [1, 2, 3]
print(a, b, c) # 1 2 3

# 单个下划线表示这个东西不需要
a, b, _ = [1, 2, 3]
print(a, b) # 1 2

# *表示把多出来的元素合成放到列表中
x, *y, z = [1, 2, 3, 4]
print(x, y, z) # 1 [2, 3] 4

python与用户交互

1
2
3
4
5
6
7
8
9
10
print('你好啊!')
s = input() # 让程序暂停,用户输入什么,就会输出什么,输出的永远是字符串
print(s)
print('--------------------')


# 你好啊!
2
2
--------------------

无论输入什么数据类型,input接收值都是字符串

格式化输出三种形式

f- string

f 使得 {} 有了特殊意义

1
2
3
4
5
s1 = 'name'
s2 = 'cwz'
print(f'{s1} {s2}') # name cwz

print(f'{20:.2f}') # 20.00

占位符

1
print(('my name is %s') % ('cwz'))  # my name is cwz

format

1
2
3
name = 'neo'
age = 19
print('{} {}'.format(name, age)) # neo 19

数字类型内置方法

整型

  • 整数, 1/2/3/12/2019
  • 整形用来描述什么, 身高/年龄/体重
1
2
age = 18
height = 180

浮点型

浮点数,小数

1
2
salary = 10
print(salary)

复数

1
2
3
z = 1 + 2j
print(z.real,z.imag)
## 1.0 2.0

数字类型方法

1
2
3
4
5
6
print(pow(2,3))  # 幂运算
print(1.2+2.3) # 3.5
print(0.1+0.2) # 0.30000000000000004
print(round(0.1+0.44,1)) # 0.5 四舍五入
print(abs(-1)) # 绝对值
print(divmod(16,3)) # 运算结果(商数, 余数)

浮点数计算会有误差,小数精准

这就是机器进行二进制计算引入的误差,为了消除这样的误差,进行更加精确的浮点计算,就要是用到decimal模块。

1
2
3
4
5
6
from decimal import *
a = Decimal('0.1') # Decimal函数传入的浮点数必须加引号,构成字符串形式,传入整数就不用了
b = Decimal('0.2')
print(type(a+b),a+b) # <class 'decimal.Decimal'> 0.3

print(Decimal(0.1)) # 0.1000000000000000055511151231257827021181583404541015625 Decimal函数传入浮点数并不精确

小数的精准计算:

1
2
3
4
5
6
7
from decimal import *
getcontext().prec = 4 # 设置有效数字为4
print(Decimal('2.2')/Decimal('1.3')) # 1.692
from decimal import *
print(Decimal('3.141592653').quantize(Decimal('0.0000'))) # 设定小数位数 这里设置了4位

# 打印结果:3.1416

字符串内置方法

作用:描述姓名

定义:单引号 / 双引号 / 三单引号 / 三双引号

1
2
3
name = 'neo'
gender = 'male'
print(name, gender)
  • 三个单引号或三双引号可以换行
1
2
3
4
5
6
poem = '''
When I was a young man, I had liberty, but I did not see it.
I have time, but I did not know it. I have love, but I did not feel it.
Many decades would pass before I understood the meaning of all three.
'''
print(poem)
  • 引号检测机制
1
2
print("neo's name is neo")  # 如果字符串中需要有单引号,要用双引号包裹整个字符串
print('''neo's name is "neo"''')
  • 转义
1
2
print('neo\'s name is "neo"')   # neo's name is "neo"
print('\tneo') # \t 4个空格,缩进
  • 换行 \n
1
2
3
4
5
print('When I was a young man, I had liberty, but I did not see it.\nI have time, but I did not know it. I have love, but I did not feel it.\nMany decades would pass before I understood the meaning of all three.')
# 打印结果:
When I was a young man, I had liberty, but I did not see it.
I have time, but I did not know it. I have love, but I did not feel it.
Many decades would pass before I understood the meaning of all three.
  • r 取消转义
1
2
print(r'\ta\na')
# 打印结果:\ta\na
  • \r \r 默认表示将输出的内容返回到第一个指针,这样的话,后面的内容会覆盖前面的内容

字符串运算

1
2
print('neo' + '123')   # neo123
print('neo'* 4) # neoneoneoneo

字符串常用内置方法

优先掌握:

  1. 索引取值
1
2
s = 'hello world'
print(s[1]) # 取到e
  1. 切片
1
2
3
4
s = 'hello world'
print(s[0:4]) # hell
print(s[4:0:-1]) # olle
print(s[:]) # hello world
  1. 长度 len
1
2
s = 'hello world'
print(len(s)) # 字符长度为11
  1. 成员运算 in / not in
1
2
3
s = 'hello world'
print('hello' in s) # True
print('hello' not in s) # False
  1. 移除strip
1
2
3
4
5
s = '     hello world    '
print(s.strip()) # hello world 默认去除两端空白

s = ' **hello world **'
print(s.strip('* ')) # hello world
  1. split切分
1
2
s = 'cwz|19|180|140'
print(s.split('|')) # ['cwz', '19', '180', '140']
  1. 循环
1
2
3
4
5
6
7
8
9
10
11
s = 'cwz123'
for i in s:
print(i)

# 打印结果:
c
w
z
1
2
3

掌握:

  1. startswith / endswith 以…开始 / 以…结束
1
2
3
s = 'hello world'
print(s.startswith('hello')) # True
print(s.endswith('world')) # True
  1. lstrip或rstrip
1
2
3
4
s1 = '**hello world**'
s2 = '**hello world**'
print(s1.lstrip('*')) # hello world**
print(s2.rstrip("*")) # **hello world
  1. lower或upper
1
2
3
s3  ='HellO WOrLD'
print(s3.lower())
print(s3.upper())
  1. rsplit
1
2
3
s4 = 'cwz|123|neo|140'
print(s4.split('|',1)) # ['cwz', '123|neo|140']
print(s4.rsplit('|',1)) # ['cwz|123|neo', '140']
  1. join
1
2
3
s4 = 'cwz|123|neo|140'
s_list = s4.split('|')
print('*'.join(s_list) # cwz*123*neo*140
  1. replace
1
2
s5 = 'hello world'
print(s5.replace('h', '6')) # 6ello world
  1. isdigit和isalpha
1
2
3
s6 = '122324'
print(s6.isdigit()) # True 判断是否全为数字
print(s6.isalpha()) # False 判断是否全为字母

其他操作:

  1. find / rfind / index / rindex / count
1
2
3
4
5
6
7
8
9
10
11
s = 'my name is cwz, age is 20'

print(s.find('m')) # 0 find查找索引值,找到第一个就不往后找了,找不到返回-1

print(s.rfind('s')) # 21 rfind从右往左查找索引值

print(s.index('s')) # 9 返回索引值

print(s.rindex('s')) # 21

print(s.count('s')) # 2 计数
  1. center()、ljust()、rjust()、zfill()
1
2
3
4
5
6
7
8
9
s = 'hello world'

print(s.center(20,'*')) # ****hello world***** 居中

print(s.ljust(20, '*')) # hello world********* 居左

print(s.rjust(20, '#')) # #########hello world 居右

print(s.zfill(20)) # 默认用0填充 000000000hello world
  1. expandtabs()
1
2
s = 'aaa\tbbb'
print(s.expandtabs()) # aaa bbb 默认制表符8个字符
  1. capitalize()、swapcase()、title()
1
2
3
4
5
6
7
s = 'HeLlO WoRlD'

print(s.capitalize()) # Hello world 首字母大写,其他小写

print(s.swapcase()) # hElLo wOrLd 大小写转换

print(s.title()) # Hello World 每个单词首字母大写

有序or无序:

字符串可以索引,有序

可变or不可变:

字符串值变id值改变,—> 字符串不可变

列表常用方法

作用:

[]内存储多个值,各元素以逗号隔开

定义方式:

lt = [1,23,4]

使用方法:

优先掌握:

  1. 索引取值 / 索引修改值
1
2
3
4
5
lt = [1,2,3,4,5]
print(lt[1]) # 2

lt[0] = 66
print(lt) # [66, 2, 3, 4, 5]
  1. 切片
1
2
lt = [1,2,3,4,5]
print(lt[0:4]) # [1, 2, 3, 4]
  1. 成员运算
1
2
3
4
lt = [1,2,3,4,5]
print(1 in lt) # True

print(0 in lt) # False
  1. for 循环
1
2
3
lt = [1,2,3,4,5]
for i in lt:
print(i)
  1. append 追加值
1
2
3
lt = [1,2,45]
lt.append([12,3]) # [1, 2, 45, [12, 3]]
print(lt)
  1. del 删除值
1
2
3
lt = [1,2,3,4,5]
del lt[4]
print(lt) # [1,2,3,4]
  1. len
1
2
lt = [1,23,4,[8,5],'www']
print(len(lt)) # 5

需要掌握:

  1. sort
1
2
3
4
# sort
lt = [1,23,8,9,4,21,412]
lt.sort() # 排序
print(lt) # [1, 4, 8, 9, 21, 23, 412]
  1. reverse
1
2
3
4
# reverse 反转
lt = [9,23,1,4,0,8]
lt.reverse() # 列表反转
print(lt) # [8, 0, 4, 1, 23, 9]
  1. remove
1
2
3
4
# remove
lt = [9,23,1,4,0,8]
lt.remove(9) # 按值删除
print(lt) # [23, 1, 4, 0, 8]
  1. pop
1
2
3
lt = [9,23,1,4,0,8]
lt.pop(1) # 按索引删除值
print(lt) # [9, 1, 4, 0, 8]
  1. extend
1
2
3
4
5
# extend
lt1 = [9,23,1,4,0,8]
lt2 = [1111,2222]
lt1.extend(lt2) # 扩展列表
print(lt1) # [9, 23, 1, 4, 0, 8, 1111, 2222]
  1. copy
1
2
# copy
print([1,23,4,0].copy()) # [1, 23, 4, 0]
  1. clear
1
2
3
4
# clear
lt = [9,23,1,4,0,8]
lt.clear() # 清空列表
print(lt) # []
  1. count
1
2
3
# count
lt = [9,23,1,4,0,1,23,4]
print(lt.count(1)) # 计数 2
  1. index
1
2
3
# index
lt = [9,23,1,4,0,8]
print(lt.index(0)) # 返回索引值 4
  1. insert
1
2
3
4
# insert
lt = [9,23,1,4,0,8]
lt.insert(0, 777) # 按索引前插入值
print(lt) # [777, 9, 23, 1, 4, 0, 8]

有序or无序:

能索引取值,列表有序

可变or不可变:

列表可变

元组内置方法

作用

元组可以看成只可取不可修改的列表,元组一创建就被写死了

定义方式

()内用逗号隔开多个元素(可以为任意数据类型)

1
2
3
4
5
6
tup = tuple((1, 2, 3))
print(tup, type(tup))

# 如果元组只有一个元素,必须得加逗号
tup1 = (1,)
print(tup1, type(tup1))

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
tup = (1,2,3,4,5,)

# 1.索引取值
print(tup[1]) # 2

# 2.切片
print(tup[1:4]) # (2, 3, 4)

# 3.for循环
for i in tup:
print(tup)

# 4.len长度
print(len(tup)) # 5

# 5.in / not in
print(0 in tup) # False

# 6.index获取索引
print(tup.index(1)) # 0

# 7.count计数
print(tup.count(1)) # 1

有序or无序

元组能索引取值,是有序的

可变or不可变

不可变

元组与列表的区别

列表可变的原因是:索引所对应的值的内存地址是可以改变的

元组不可变的原因是:索引所对应的值的内存地址是不可以改变的,或者反过来说,只要索引对应值的内存地址没有改变,那么元组是始终没有改变的。

字典内置方法

作用

存储多个值,对每个数据有描述意义

定义方式

{}内用逗号隔开多个键key(具有描述意义,不能为可变数据类型):值value(任意数据类型)

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
dic = {'a':1, 'b':2}

# 1.按key取值
print(dic['a']) # 1

# 2.按key修改值
dic['a'] = 666
print(dic) # {'a': 666, 'b': 2}

dic['c'] = 3 # 没有就加值
print(dic) # {'a': 666, 'b': 2, 'c': 3}

# 3.for循环
for i in dic:
print(i) # 只能取到key值

# 4.in / not in
print('a' in dic) # True

# 5.len
print(len(dic)) # 3

# 6.keys/values/items
print(dic.keys()) # dict_keys(['a', 'b', 'c'])
print(dic.values()) # dict_values([666, 2, 3])
print(dic.items()) # dict_items([('a', 666), ('b', 2), ('c', 3)])

# 7.get
print(dic.get('a')) # get取值,如果没有返回None

# 8.update
dic1 = {'a': 1, 'c': 2}
dic2 = {'b': 1, 'd': 2}
dic1.update(dic2)
print(dic1) # {'a': 1, 'c': 2, 'b': 1, 'd': 2}

# 9.fromkeys 创建一个新字典,如没有value值,默认None
print(dic.fromkeys(['a','b','c'], 1)) # {'a': 1, 'b': 1, 'c': 1}

# 10.# setdefault # 字典有这个key,就不修改,没有则增加
dic.setdefault('j', 2)
dic.setdefault('a', 2)
print(dic)

有序or无序

字典无序

可变or不可变

字典可变

集合内置方法

作用

进行 交集 / 并集 / 补集等运算,可以去重,但是集合内元素是乱序的

定义方式

{}内以逗号隔开多个元素(不能可为变数据类型)

1
2
3
s = {'a', 'a', 'a', 'a', 1, 'v', 2, 2, 'c', 3, 3, 4, 5, 6}  # 对于数字而言,不会乱序;但是对于其他,就乱序
print(s)
# {1, 2, 'a', 3, 4, 5, 6, 'v', 'c'}

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
se1 = {'cwz', 'neo', 'woods'}
se2 = {'reese', 'chars', 'cwz'}

# 1.并集
print(se1 | se2) # {'neo', 'reese', 'cwz', 'woods', 'chars'}

# 2.交集
print(se1 & se2) # {'cwz'}

# 3. 差集
print(se1 - se2) # {'neo', 'woods'}

# 4.补集
print(se1 ^ se2) # {'reese', 'chars', 'neo', 'woods'}

# 5.add
se1.add('sad')
print(se1) # {'neo', 'sad', 'woods', 'cwz'}

# 6.remove / discard
se1.remove('neo') # 没有的,删除用remove会报错
print(se1) # {'sad', 'woods', 'cwz'}

se2.discard('chars') # 没有的,删除用discard不会报错
print(se2) # {'cwz', 'reese'}

# 7.pop
se1.pop() # 随机删除值
print(se1) # {'woods', 'cwz'}

有序or无序

无序

可变or不可变

可变

深浅拷贝

可变or不可变

id值不可变,就是在原值基础上修改,为可变数据类型;

id值变化,就是重新申请一块内存空间放入新值,为不可变数据类型。

拷贝

如果lt2是lt1的拷贝对象,则lt1内任何数据类型的元素变化,lt2也跟着变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lt1 = [1,2,3,4,'a',[1,23,5]]
lt2 = lt1
print(lt1)
print('lt1_id: ', id(lt1))
lt1.append('b')
print('*'*50)
print(lt1)
print('lt1_id: ', id(lt1))
print(lt2)
print('lt2_id: ', id(lt2))

# 打印结果:
[1, 2, 3, 4, 'a', [1, 23, 5]]
lt1_id: 1990616507080
**************************************************
[1, 2, 3, 4, 'a', [1, 23, 5], 'b']
lt1_id: 1990616507080
[1, 2, 3, 4, 'a', [1, 23, 5], 'b']
lt2_id: 1990616507080

浅拷贝

如果lt2是lt1的浅拷贝对象,则lt1内的不可变元素发生了变化,lt2不变;

如果lt1内的可变元素发生了改变,则lt2跟着改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import copy

lt1 = [1, 2, 3, 4, 'a', [1, 23, 5]]
lt2 = copy.copy(lt1)
lt1.append(99)
print('lt1: ', lt1)
print('lt1_id: ', id(lt1))
print('lt2: ', lt2)
print('lt2_id: ', id(lt2))
print('*'*50)
lt1[5].append('qq')
print('lt1[5]: ', lt1)
print('lt1[5]_id: ', id(lt1))
print('lt2: ', lt2)
print('lt2_id: ', id(lt2))

# 打印结果:
lt1: [1, 2, 3, 4, 'a', [1, 23, 5], 99]
lt1_id: 2049177903816
lt2: [1, 2, 3, 4, 'a', [1, 23, 5]]
lt2_id: 2049299510728
**************************************************
lt1[5]: [1, 2, 3, 4, 'a', [1, 23, 5, 'qq'], 99]
lt1[5]_id: 2049177903816
lt2: [1, 2, 3, 4, 'a', [1, 23, 5, 'qq']]
lt2_id: 2049299510728

深拷贝对象

如果lt2是lt1的深拷贝对象,则lt1内的不可变数据类型元素改变,lt2不变;

如果lt1内的可变数据类型元素改变,lt2不变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import copy

lt1 = [1, 2, 3, [4, 5, 6]]
lt2 = copy.deepcopy(lt1)

print('id(lt1)', id(lt1))
print(id(lt1[0]))
print(id(lt1[1]))
print(id(lt1[2]))
print(id(lt1[3]))
print(id(lt1[3][0]))
print(id(lt1[3][1]))
print(id(lt1[3][2]))

print('*' * 50)

print('id(lt2)', id(lt2))
print(id(lt2[0]))
print(id(lt2[1]))
print(id(lt2[2]))
print(id(lt2[3]))
print(id(lt2[3][0]))
print(id(lt2[3][1]))
print(id(lt2[3][2]))

# 打印结果:
id(lt1) 2156612313800
140728121221968
140728121222000
140728121222032
2156612313736
140728121222064
140728121222096
140728121222128
**************************************************
id(lt2) 2156760304520
140728121221968
140728121222000
140728121222032
2156642018504
140728121222064
140728121222096
140728121222128

异常处理

什么是异常处理 (处理异常,报错error)

1
2
3
4
5
6
7
print(1 / 0)  # 报了0除错误

# 打印结果:
Traceback (most recent call last):
File "D:/pycharm_project/day07/01异常处理.py", line 18, in <module>
print(1 / 0)
ZeroDivisionError: division by zero

捕获异常

1
2
3
4
5
6
7
8
9
10
11
try:

print('----1----')
f = oen('a.txt', 'r') # 路径不对, 是错误的代码
print('----2----')

except: # 捕获异常
pass

# 输出结果:
----1----

捕获具体异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
try:
1 / 0
y = input('请输入数字:')
y += 10
except TypeError as e:
print('error:', e)
except ZeroDivisionError as a:
print('error:', a)

print(x + 10)

# 打印结果:
error: division by zero
11
try:
1 / 0
y = input('请输入数字:')
y += 10
except Exception as e: # 只要捕捉Exception
print('error:', e)

不需要记住具体异常,只要捕捉Exception

finally (无论是否报错,都会执行finally下的代码)

1
2
3
4
5
6
7
8
try:
1 / 0
y = input('请输入数字:')
y += 10
except Exception as e: # 只要捕捉Exception
print('error:', e)
finally: # 无论是否报错,都会执行finally下的代码
print(1)

raise (可以自定义异常)

1
2
3
4
5
6
7
8
9
10
s = input('请输入数字:')
# print(s.isalpha()) # isalpha() 如果全是字母,则输出True
if s.isalpha():
raise TypeError('报错了, 请输入数字')

# 打印结果:
Traceback (most recent call last):
File "D:/test2.py", line 82, in <module>
raise TypeError('报错了, 请输入数字')
TypeError: 报错了, 请输入数字

断言assert

1
2
3
4
5
6
assert 1 == 1

try:
assert 1 == 2
except Exception as e:
print(e)

基本运算符

算术运算符

运算符 描述 实例
+ a + b
- a - b
* a * b
/ a / b
% 取余 a % b
// 整除 a // b
** 幂运算 a b 23=8

比较运算符

假设变量a = 10, b = 20

运算符 描述 实例
== 等于,比较对象是否相等 a == b 返回False
!= 不等于,比较对象是否不相等 a != b 返回True
< 小于 a < b 返回True
<= 小于等于 a <= b 返回True
> 大于 a > b 返回False
>= 大于等于 a >= 返回False

赋值运算符

1
= += -= /= *= %= //= **=

逻辑运算符

运算符 实例
and and 左右两个条件都为True,则为True,否则为False
or or 左右两个条件只要有一个满足则为True,否则为False
not not 否,如果条件为True,则为False,如果条件为False,则为True
1
2
3
4
5
6
7
8
9
10
11
name = 'cwz'
height = 180
weight = 140

print(name == 'cwz' and height == 180) # True
print(name == 'cwz2' and weight == 140) # False

print(name == 'cwz2' or weight == 140) # True
print(name == 'cwz2' or weight == 120) # False

print(not name == 'cwz') # False

身份运算符

运算符 描述 实例
is is判断两个标识符是不是引用自一个对象 x is y, 如果引用自同一对象,返回True,否则返回False
is not is not 判断两个标识符是不是引用自不同对象 x is not y, 如果引用来自不同对象,返回True,否则返回False

is和==的区别:is用于判断两个变量引用对象是否为同一个(是否在同一块内存空间中), ==用于判断引用变量的值是否相等。

成员运算符

运算符 描述 实例
in 如果在指定序列中找到值,返回True,否则False x = 1, y = [1,2,3,4], x in y ->返回True
not in 如果在指定序列中没找到值,返回True,否则False x = 1, y = [1,2,3,4], x not in y ->返回False

位运算符

按位运算符把数字看作二进制来进行来进行计算。

下表中变量 a 为 60,b 为 13,二进制格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 0011 1100

b = 0000 1101

-----------------

a&b = 0000 1100

a|b = 0011 1101

a^b = 0011 0001

~a = 1100 0011

python运算符优先级

优先级高的用括号括起来就行了。。。

流程控制

流程控制之if判断

流程控制 就是 控制 变量变化的一个方向

单分支结构

1
2
if 条件:   # 条件成立执行下面的代码
代码

双分支结构

1
2
3
4
if 条件1:   # 条件1成立执行代码1,不成立执行代码2
代码1
else:
代码2

多分支结构

1
2
3
4
5
6
7
8
9
10
11
12
if 条件1:   
代码1
elif 条件2: # if后面条件成立,执行代码1,不会走下一步。只有if后面条件不成立才会走到这一步,才会执行代码2
代码2
elif 条件3:
代码3
elif 条件4:
代码4
......
(elif 可以有很多)
else:
代码

练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'''
如果 成绩>=90,打印"优秀"
如果 成绩>=80 并且 成绩<90,打印"良好"
如果 成绩>=70 并且 成绩<80,打印"普通"
其他情况:打印"差"
'''

grade = input('请输入你的成绩:')

grade_int = int(grade)

if grade_int>=90:
print('优秀')
elif grade_int >=80:
print('良好')
elif grade_int >=70:
print('普通')
else:
print('差')

找bug的绝招,打印变量,查看变量的变化过程 —》 debug的来源

流程判断之while循环

循环 —> 有规律的重复干一件事

语法

1
2
3
4
while 条件:  # 条件成立运行代码,不成立结束while循环
代码 # 代码执行结束后会进入下一次循环
while True:
print(1)

这个程序会无限打印输出1, 我们需要停下来怎么办?

while + break

打印1-100:

1
2
3
4
5
6
count = 0
while True:
if count == 100:
break # break终止循环
count += 1
print(count)

while + continue

打印1-100,不打印50

1
2
3
4
5
6
7
8
count = 0
while True:
if count == 100:
break
count += 1
if count == 50:
continue # continue 跳出本次循环,不执行下面的代码
print(count)

打印1-100的偶数之和(不包括[22,46,68,98])

1
2
3
4
5
6
7
8
9
10
11
count = 0
sum_count = 0
while 1:
if count == 100:
break
count += 2
if count in [22,46,68,98]:
continue
sum_count += count
print(count)
print('和为:', sum_count )

tag中间变量 控制while循环

改进代码:

1
2
3
4
5
6
7
8
9
count = 0
sum_count = 0
while count < 100:
count += 2
if count in [22,46,68,98]:
continue
sum_count += count
print(count)
print('和为:', sum_count )

练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 猜年龄游戏,三次机会

age = 19
count = 0
while count < 3:
age_inp = input('请输入你的年龄:').strip()
age_inp_int = int(age_inp)
if age_inp_int == age:
print('猜对了')
break
elif age_inp_int < age:
print('猜小了')
else:
print('猜小了')

count += 1
print(f'你还有{3 - count}次机会')

while + else (仅作了解)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
count = 0
while count < 5:
count += 1
print(count)
else:
print('没有被break打断我就能出来')


# 打印结果:
1
2
3
4
5
没有被break打断我就能出来

while… else… 循环过程没有被break中断就会执行else后面的代码,否则不会执行else后面的代码。

控制流程之for循环

基本语法

1
2
3
4
5
6
7
8
9
10
11
for 变量名(会拿到容器类元素的每一个值) in 容器类元素:
print(变量名)
for i in range(5):
print(i)

# 打印结果:
0
1
2
3
4

while可以循环一切事物

for 循环提供了一种手段,不依赖索引取值

for+break

1
2
3
4
for i in range(1, 101):    # 取1-100,range顾头不顾尾
if i == 50:
break # 中断循环,只取到1-49
print(i)

for+continue

1
2
3
4
for i in range(1, 101):
if i == 51:
continue # continue跳出本次循环,不执行下面代码
print(i)

for+else

1
2
3
4
5
for i in range(1, 101):
if i == 51:
break
print(i)
print('没有被break中断我就出来')

for循环不被break终止就执行else后面的代码,否则就不执行

for循环打印lodaing

1
2
3
4
5
6
7
8
9
10
11
import time
print('Loading', end='')
for i in range(10):
print('.', end='')
time.sleep(0.2)
print(1, end='*') # print后面的end控制打印的状态
print(1, end='*')
print(1, end='*')
print(1, end='*')

# 打印结果:1*1*1*1*

for循环习题

1
2
3
4
5
6
7
8
for i in range(1, 13):      # 控制月
for j in range(1,32): # 控制日
if j == 2 and i > 28:
continue
if j in [4, 6, 9, 11] and i > 30:
continue

print(f'{j}{i}日刷牙')