第二篇:垃圾回收机制、变量、基本数据类型及内置方法、运算符
垃圾回收机制与小整数池
变量 = 值:变量值会产生新的空间
变量b = 变量a:变量值不会产生新的空间(变量值的引用计数加一)
垃圾回收机制⭐⭐⭐⭐⭐
垃圾:当一个变量值被绑定的变量名的个数为0时,该变量值无法被访问到,称之为垃圾垃圾回收机制:python解释器自带的一种专门来回收不可用变量值所占用的内存空间
引用计数
栈区:存放变量名与内存地址的对应关系
堆区:存放变量值
# 引用计数: 内存中的数据如果没有任何的变量名与其有绑定关系,那么会被自动回收 x = 10 # 10的引用计数为1 y = x # 10的引用计数为2 l = ['a','b',x] # 10的引用计数为3 del l[2] # 解除变量名l[2]与值10的绑定关系,10的引用计数变为2 print(l[2]) # IndexError: list index out of range del x # 解除变量名x与值10的绑定关系,10的引用计数变为1 print(x) # NameError: name 'x' is not defined y = 20 # 10的引用计数为0 print(y) # 20
标记清除
# 标记清除: 当内存快要被某个应用程序占满时会自动触发,停止程序的运行,检测所有变量与值的绑定关系, 给能直接引用或间接引用的对象(变量)打上存活标记,清除未被标记的对象(变量) # 标记清除是用来解决循环引用(交叉引用)带来的内存泄露问题 l1 = [111] l2 = [222] l1.append(l2) # l1=[值111的内存地址,l2列表的内存地址] l2.append(l1) # l2=[值222的内存地址,l1列表的内存地址 ] print(l1) # [111, [222, [...]]] print(l2) # [222, [111, [...]]] del l1 # l1的引用计数变为1 del l2 # l2的引用计数变为1
分带回收
- 背景:基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的
- 分代回收: 根据值存活时间的不同,划为不同的等级,等级越高垃圾回收机制扫描的频率越低
小整数池⭐⭐
# 小整数池[-5,256]:Python 对于小整数会进行对象池化,因此在这个范围内的整数无论在何处使用,都是同一个对象 >>> a = 256 >>> b = 256 >>> print(a is b) True >>> a = 257 >>> b = 257 >>> print(a is b) False # 字符串的驻留 >>> a = 'jiang' >>> b = 'jiang' >>> print(a is b) True >>> x = 'jiang:18' >>> y = 'jiang:18' >>> print(x is y) False
变量、常量、输入输出
变量(可以变化的量)
变量名的命名规范
# 变量命名规则 1.只能包含数字,字母,下划线 2.数字不能开头 3.关键字不能作为变量名 # 通常变量名的命名有两个流派: 驼峰体(前端语言js推荐的命名方式) UserName 下划线(python推荐的命名方式) user_name
变量的基本使用(先定义,后引用)⭐⭐⭐
# 定义-》存 name = 'jiang' age = 18 # 引用-》取 print(name) # jiang print(age) # 18
变量的三大组成部分⭐⭐⭐⭐⭐
变量名-->是指向等号右侧值的内存地址的,用来访问等号右侧的值 赋值符号:将变量值的内存地址绑定给变量名 变量值:代表记录的事物的状态
变量的三个特征(id type value)
name='jiang' # id:返回该变量的内存地址 print(id(name)) # 2390492606064 # type:返回该变量对应的数据类型 print(type(name)) # <class 'str'> # value:值本身 print(name) # jiang
常量(不可变化的量)
python里面压根没有常量,通常将全大写的变量名看作常量(预定俗成)
MYNAME = 'yuanxiaojiang' MYNAME = 'wuxiaofeng' print(MYNAME) # wuxiaofeng
输入输出
输入
name = input('input you name:') # input you name:yuan
格式化输出
# 占位符 %s %d name = 'yuan' age = 18 print('my name is %s my age is %s'%(name,age)) # my name is yuan my age is 18 # 谁先来谁先坐,个数必须一致不能多也不能少 # %d只能给数字占位,%s可以给任意数据类型占位 # f:python3.5后推出 x = 'yuan' y = [111,222] res = f'{x},{y}' print(res) # yuan,[111, 222] # format() # 第一种:按位置占位,跟%s原理一致 print('my name is {},my age is {}'.format('yuan',18)) # 第二种:按索引占位 print('my name is {1},my age is {0}'.format(18,'yuan')) # 第三种:关键字传参 print('my name is {name},my age is {age}'.format(age=18,name='yuan'))
基本数据类型
- 可变类型:值改变,id不变
- 不可变类型:值改变,id也变
数字类型(int、float、不可变)
# 整形int(不可变) age = 18 print(type(age)) # <class 'int'>
x=22
print(bin(x)) # 0b10110 二进制
print(oct(x)) # 0o26 八进制
print(hex(x)) # 0x16 十六进制
# 浮点型float(不可变) height = 1.87 print(type(height)) # <class 'float'> # 数字类型的其他使用 level = 1 level=level + 1 print(level) # 2 print(10 *3) # 30 print(10 + 3.3) # int与float之间可以相加 age = 19 print(age > 18)
字符串类型(str 、不可变、有序)⭐⭐⭐
# 用引号('',"",''' ''',""" """,)包含的一串字符 info = 'yuan' print(type(info)) # <class 'str'>
# 字符串的嵌套:外层用单引号,内层用双引号,反之亦然 print("my name is 'yuanxiaojiang'") # my name is 'yuanxiaojiang' print('my name is \'yuanxiaojiang\'') # my name is 'yuanxiaojiang' # 字符串之间可以相加,但仅限于str与str之间进行 print('my name is '+'yuanxiaojiang') # my name is yuanxiaojiang print('='*10) # ========== 字符串数乘 # 字符串的索引 a = 'jiang' print(a[1]) # i
strip() lstrip() rstrip()
# 默认去除字符串首尾空格,也可指定其它符号 print(' jason '.strip()) # jason print('$$jason$$$'.strip('$')) # jason print('% ¥#jason&*)'.strip('% ¥#*')) # jason& 指定去除多个字符 print('$$jason$$$'.lstrip('$')) # jason$$$$ 只去除左边字符 print('$$jason$$$'.rstrip('$')) # $$$$jason 只去除右边字符
split() rsplit()
# 切分,针对按照某种分隔符组织的字符串,可以用split将其切分成列表,进而进行取值 data = 'jason|123|handsome' print('data'.split('|')) # ['jason','123','handsome'] 切割的顺序是从左往右的 username,password,info = data.split('|') print(data.split('o',1)) # ['jas','n|123|handsome'] 从左往右只切一个 print(data.rsplit('o',1)) # ['jason|123|hands','me'] 从右往左只切一个
lower() upper() capitalize() swapcase() title()
print('JaS1oN'.lower()) # jas1on 转小写 print('JaS1oN'.upper()) # JAS1ON 转大写 # 首字母大写 print('hEllo WorlD'.capitalize()) # Hello world # 大小写互换 print('hEllo WorlD'.swapcase()) # HeLLO wORLd # 每隔二单词首字母大写 print('hEllo WorlD'.title()) # Hello World
startswith() endswith()
print('yuan is dsg'.startswith('yuan')) # True 判断字符串是否以什么什么开头 print('yuan is dsg'.endswith('n')) # False 判断字符串是否以什么什么结尾
format()
# 第一种:按位置占位,跟%s原理一致 print('my name is {},my age is {}'.format('yuan',18)) # 第二种:按索引占位 print('my name is {1},my age is {0}'.format(18,'yuan')) # 第三种:关键字传参 print('my name is {name},my age is {age}'.format(age=18,name='yuan'))
join()
# 将容器类型中的多个元素通过指定字符拼接成一个字符串,join拼接时容器中的每个元素类型都要一样 res_list = ['jason','123','handsome'] res_str = '$'.join(res_list) print(res_str) # jason$123$handsome
replace()
str = 'yuan xiao jiang is beautiful jiang' print(str.replace('jiang','jun')) # yuan xiao jun is beautiful jun print(str.replace('jiang','long',1)) # yuan xiao long is beautiful jiang
isdigit()
age = input('请输入你的年纪:') print(age,age.isdigit()) # 18 True
find() rfind() index() rindex()
# find和index的区别是,find找不到返回-1, index找不到报错 # 找到返回首字母的索引值 s = 'kevin is dsb o and kevin is sb' print(s.find('dsb')) # 返回的是d字符所在的索引值 print(s.find('xxx')) # 找不到不报错返回-1 print(s.find('i',0,3)) # 通过索引来限制查找范围 print(s.index('o')) # 返回所传字符所在的索引值 print(s.index('xxx')) # 找不到则报错 print(s.index('v',0,3)) # 通过索引来限制查找范围,顾头不顾尾
count()
# 统计指定的字符出现的次数 print('yuan wu lu'.count('u')) # 3
center() ljust() rjust() zfill()
# str.center(指定字符串总长度,'需要插入的字符') print('jason'.center(12,'*')) # ***jason**** print('jason'.ljust(12,'$')) # jason$$$$$$$ print('jason'.rjust(12,'$')) # $$$$$$$jason # str.zfill(指定字符串总长度) 左侧其余位置填充0 print('jason'.zfill(12)) # 0000000jason
列表(list、可变、有序)⭐⭐⭐⭐⭐
# 定义:在[]内用逗号分隔开多个任意类型的值,一个值称为一个元素 l = [10, 3.1, 'aaa', ['bbb', 'ccc'], 'ddd'] print(type(l)) # <class 'list'> print(l) # [10, 3.1, 'aaa', ['bbb', 'ccc'], 'ddd'] print(l[3][1]) # ccc print(l[-1]) # ddd # 能够被for循环的就能够被list转换,list内部原理就是for循环取值,然后一个个塞到列表中去 print(list('abc')) # # ['a','b','c'] print(list({'name': 'jason','password': '123'})) # ['name','password']
append() insert() extend()
# 往列表中添加元素 l = [11,22,33,44,55] l1 = [88,77] # 尾部插入 l.append(66) # [11,22,33,44,55,66] # 索引插入 l.insert(2,l1) # [11,22,[88,77],33,44,55,66] # 添加容器类型数据(通过for循环一个个追加到列表的尾部) l.extend(l1) # [11, 22, [88, 77], 33, 44, 55, 66, 88, 77]
del pop() remove() clear()
# 删除列表元素 l = [11,22,33,44,55] del l[2] # [11,22,44,55] l.pop(2) # [11, 22, 55] 索引删除(不指定索引默认删除最后一个) l.remove(11) # [22,55] 指定要删除的元素 # 清空列表 l = [11,'22',[33,44]] print(l.clear()) # None
count()
# 查询指定元素的个数 l = [111,[111,555],[111,555]] print(l.count(111)) # 1 print(l.count([111,555])) # 2
reverse() sort()
# reverse():将列表反转 l = [11,22,[31,32]] l.reverse() # 没有返回值 print(l) # [[31, 32], 22, 11] # sort():将列表排序(默认情况:从小到大) l = [11,33,22] l.sort() print(l) # [11, 22, 33] l.sort(reverse=True) # 可以通过指定参数来修改默认的排序规则(降序) print(l) # [33, 22, 11]
字典类型(dict、可变、无序)⭐⭐⭐⭐⭐
# {key:value},其中key为不可变类型(通常为字符串类型) # key不能重复,要唯一标识一条数据,如果重复了,会按照最后一组重复的键值对存储 d1 = {'name': 'yuan','password': 123} d2 = dict(name='yuan',password=123) # 按key取值、改值、添加值 d = {'name': 'yuan','password': 123} d['name'] = 'jiang' print(d['name']) # key不存在则报错,建议用get() print(d.get('name')) d['age'] = 18 # 赋值语句当key不存在时,会自动新增一个键值对
del pop() clear()
d = {'name': 'yuan','password':123,'age':20} del d['name'] d.pop('age') print(d) # {'password': 123} d = {'name': 'yuan','password':123,'age':20} d.clear() print(d) # {}
key() value() items()
# 键keys(),值values(),键值对items() d = {'name': 'yuan','age':20} print(d.keys()) # dict_keys(['name', 'age']) print(d.values()) # dict_values(['yuan', 20]) print(d.items()) # dict_items([('name', 'yuan'), ('age', 20)])
get()
# get() 根据key获取value d = {'name': 'yuan','age':20} print(d['age']) # key不存在则报错 print(d.get('nam')) # key不存在返回None print(d.get('sex','sex不存在')) # key不存在,返回传入的第二个参数
dict.formkeys()
# dict.formkeys() 快速创建一个字典 l = ['name','password','age'] print(dict.fromkeys(l,None)) # {'name': None,'password': None,'age': None} d = dict.fromkeys(l,[])# 此时name、password、age指向的是同一个列表 # 当name的列表值改变时,password和age也会跟着改变 print(d) # {'name': [],'password': [],'age': []} d['name'].append('yuan') print(d) # {'name': ['yuan'],'password': ['yuan'],'age': ['yuan']}
update()
# update() key存在则修改,不存在则新增 d = {'name': 'yuan','age': 18} d.update({'age': 28,'hobby': 'study'}) print(d) # {'name': 'yuan', 'age': 28, 'hobby': 'study'}
元组(suple、不可变、有序)⭐⭐⭐
# 元组必须传入可变类型 age=(11,22,33,44) # 本质 age=tuple([11,22,33,44]) # t1 = tuple(1) # TypeError: 'int' object is not iterable # 报错,必须传可变类型 # 定义元组时,当只有一个元素且没有用逗号时,则不是定义成元组,而是会把()去掉定义成数值或字符串等 # 在定义容器类型的时候,哪怕内部只有一个元素,你也要用逗号隔开区分一下 # print(type((1)),type(('yuan')),type((1,))) # <class 'int'> <class 'str'> <class 'tuple'> # 元组的值为不可变类型 t = (1, 2, 3, 'a', 'b', [1, 2, 3]) # t[1] = 2 # TypeError: 'tuple' object does not support item assignment # del t[1] # TypeError: 'tuple' object doesn't support item deletion t[-1][0] = '11111' # 当元组里的元素是可变的容器类型则可以改 t[-1].append(4) print(t) # t = (1, 2, 3, 'a', 'b', ['11111', 2, 3, 4])
count()
# 查询某个元素的个数 t = (1, 2, 3, 'a', 'b', ['a', 2, 3], ['a', 2, 3]) print(t.count('a')) # 1 print(t.count(['a', 2, 3])) # 2
index()
# 查询指定的元素 t = (1, 2, 3, 'a', 'b', [1, 2, 3]) print(t.index('a')) # 3 返回所传字符所在的索引值 # print(t.index('xxx')) # 找不到则报错 # print(t.index('a',0,3)) # 通过索引来限制查找范围,顾头不顾尾
集合(set、可变、无序)
# 作用:去重 print({1,3,2,1}) # {1,2,3} # 集合是可变类型,但每个元素必须是不可变类型(整形、浮点型、字符型、布尔、元组) s1 = {1,1.1,'yuan',True,(111,222)} print(s1) # {(111, 222), 'yuan', 1.1, 1} s2 = {(111,222),{'key':'value'}} # TypeError: unhashable type: 'dict' # 仅仅只写一个大括号,python默认将它当做字典类型 x = {} print(type(x)) # <class 'dict'> # 定义空集合只能用关键字set x = set() print(type(x)) # <class 'set'>
add()
s = {1,2} s.add((11,22)) # 将容器类型也当成一个元素传入 print(s) # {1, 2, (11, 22)}
remove() discard()
# remove() 删除,不存在则报错 s = {1,2,3} s.remove(1) # s.remove(4) # KeyError: 4 print(s) # {2,3} # discard() 删除,不存在不报错 s = {1,2,3} s.discard(888) print(s) # {1,2,3}
共有使用和方法
# for循环 字符串 列表 元组 字典(循环的是key) # 按索引取值 字符串 列表 元组 # 切片 字符串 列表 元祖 # len()长度 字符串 列表 元祖 字典 集合 # in、not in成员运算 字符串、列表、元祖、字典(只能判断key)、集合 # del 删除 所有类型,没有返回值 # enumerate() 字符串、列表、元组、字典
运算符
算术运算符
# + - * /(结果带小数,python2中只保留整数部分) //(结果保留整数部分) % **幂运算符 print(10 + 3) # 13 print(10 - 3.1) # 6.9 print(10 / 3) # 3.33333 print(10 // 3) # 3 print(10 % 3) # 1 print(10 ** 3) # 100
比较运算符
>、>=、<、<=、==、!=
赋值运算符(=)⭐⭐⭐
变量赋值
x = 2
print(x)
增量赋值 += *= /= %=
age = 18 age += 1 # age=age + 1 age*=3 age/=3 age%=3 age**=3 # age=age**3
链式赋值
z = y = x = 10 # 链式赋值 print(x, y, z) # 10 10 10 print(id(x), id(y), id(z)) # 1983796505168 1983796505168 1983796505168
交叉赋值
m = 10 n = 20 m,n=n,m # 交叉赋值 print(m,n) # 20 10
解压赋值
# 引入*,可以帮助我们取两头与中间的值 # *会将没有对应关系的值存成列表然后赋值给紧跟其后的那个变量名 salaries=[111,222,333,444,555] # 取前三个值 x,y,z,*right_element=salaries print(x,y,z,right_element) # 111 222 333 [444, 555] # 取后三个值 *left_element,x,y,z=salaries print(left_element,x,y,z) # [111, 222] 333 444 555 # 取中间三个值 x,*middle_element,y,z=salaries print(x,middle_element,y,z) # 111 [222, 333] 444 555 _,*middle,_=salaries print(middle) # [222, 333, 444] _,_,*middle,_=salaries print(middle) # [333,444] # 解压字典默认解压出来的是字典的key x,y,z=dic={'a':1,'b':2,'c':3} print(x,y,z) # a b c
成员运算符(in、not in)
# 判断一个字符串是否在一个大字符串中 print("jiang" in "yuanxiaojiang") # True # 判断元素是否存于列表 print(111 not in [111,222]) # False # 判断key是否存于字典 print('yuan' in {'name':'yuan','age':18}) # False 只能判断key
逻辑运算符(not、and、or)
# 优先级:not > and > or not:取反(not与紧跟其后的条件是一个不可分割整体) and:逻辑与 or:逻辑或
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现