字典,元组,集合的内置方法与垃圾回收机制

1. 字典的内置方法(重要)

# 1.类型转换
#     dict1()
# 基本不会使用, 就不博客中进行讲解

dict1 = {
    'name': '李四',
    'salary': 18000,
    'hobbies': ['play game', 'basketball']
}

# 1.按key取值
print(dict1['name'])
# >>>李四
print(dict1['xxx'])
# >>>报错 因为xxx在字典的key中不存在,所以就报错了

"""涉及到字典取值 更加推荐下面的方式"""
print(dict1.get('name'))
# >>>李四
print(dict1.get('xxx'))
# >>>None 当xxx在字典的key中不存在时,输出的则为None
print(dict1.get('xxx', False))
# >>>False 当get方法有第二个参数时,那么xxx在字典的key中不存在,就会输出第二个参数的值

# 2.字典是可变类型
print(id(dict1))
# >>>2053106393408
dict1['name'] = '王五'
print(dict1, id(dict1))
# >>>{'name': '王五', 'salary': 18000, 'hobbies': ['play game', 'basketball']} 2053106393408
# >>>根据这俩次输出的内存地址,可以得到字典时可变类型

# 3.添加键值对
dict1['age'] = 18
print(dict1)
# >>>{'name': '李四', 'salary': 18000, 'hobbies': ['play game', 'basketball'], 'age': 18}
dict1['name'] = '王五'
print(dict1)
# >>>{'name': '王五', 'salary': 18000, 'hobbies': ['play game', 'basketball'], 'age': 18}
# 当字典括号中的参数存在时,那么就会修改字典中对应key的value值,如果key不存在,那么就会在字典中生成一个k,V键值对进行存储


# 4.统计字典中键值对的个数
print(len(dict1))
# >>>3
# 与列表,字符串的len方法是一样的

# 5.成员运算
print('李四' in dict1)
# >>>False
print('name' in dict1)
# >>>True
# 字典使用成员运算的时候,只能获取到key,也只能判断是不是在key值中


# 6.删除键值对
del dict1['name']  # 通用的删除方式,与列表的del删除时一样的
print(dict1)
# {'salary': 18000, 'hobbies': ['play game', 'basketball']}

print(dict1.pop('salary'))  # 与列表的pop删除时一样的
# >>>18
print(dict1)
# >>>{'name': '李四', 'hobbies': ['play game', 'basketball']}

# 7.获取所有的键 所有的值 所有的键值对
print(dict1.keys())
# >>>dict1_keys(['name', 'salary', 'hobbies'])  可以看成是列表
for k in dict1.keys():
    print(k)
# 循环取出字典的key值

print(dict1.values())
# >>>dict1_values(['jason', 18000, ['play game', 'basketball']])  可以看成是列表
for v in dict1.values():
    print(v)
# 循环取出字典的values值

print(dict1.items())
# dict1_items([('name', '李四'), ('salary', 18000), ('hobbies', ['play game', 'basketball'])])  可以看成是列表套元组
for k, v in dict1.items():
    print(k, v)
# 循环取出字典的key与values值
"""在python2中上述三个方法(keys, values, items)就是直接返回一个列表 """

 

 

2. 字典的内置方法(了解)

# # 1.update更新字典
# dic = {'k1': 'tank', 'k2': 'tony', 'k3': 'jerry'}
# dic.update({'k1': '李四', 'k4': '王五'})
# print(dic)  # 键存在则修改 键不存在则新增
# # >>>{'k1': '李四', 'k2': 'tony', 'k3': 'jerry', 'k4': '王五'}
# # 当更新时,如果有对应的key值,那么就会将key对应的value进行更新,如果没有对应的key,那么就会生成新的键值对
#
# # 2.fromkeys()快速生成字典
# dic = dic.fromkeys(['k1', 'k2', 'k3'], [])
# print(dic)
# # >>>{'k1': [], 'k2': [], 'k3': []}
# """笔试题有可能会出现"""
# dic['k1'].append(222)
# print(dic)
# # >>>{'k1': [222], 'k2': [222], 'k3': [222]}
# # 由上面的操作可知道,fromkeys创建字典时,如果key值有多个,那么会有多个key指向一个value的内存储空间,当改变一个key时,其他的key值也会跟随一起改变

# 3.setdefault()
dic = {'k1': 111, 'k2': 222}
print(dic.setdefault('k3', 333))
# >>>333
print(dic)
# >>>{'k1': 111, 'k2': 222, 'k3': 333}
# >>>111
print(dic.setdefault('k1', '嘿嘿嘿'))
print(dic)
# >>>{'k1': 111, 'k2': 222, 'k3': 333}
# 由此可得,当输出setdefault时,如果有对应的key,那么输出的为key对应的value,不会对value进行改变,当没有key值时,会自动创建一个键值对

 

 

3. 元组内置方法

# 可以看成是不可变的列表
# 1.类型转换
# print(tuple(11))
# >>>报错
# print(tuple(11.11))
# >>>报错
print(tuple('tony'))
# >>>('t', 'o', 'n', 'y')
print(tuple([1, 2, 3, 4]))
# >>>(1, 2, 3, 4)
print(tuple({'name': 'tony'}))
# >>>('name',)
print(tuple({1, 2, 3, 4}))
# >>>(3, 1, 4, 2)
# print(tuple(True))
# >>>报错
# 由上边的输出可以得到,支持for循环的数据类型都可以转成元组,其他的转换时会报错

# 2.元组的特性
t1 = (1, 2, 3, 4)
print(type(t1))
# >>><class 'tuple'>
t1 = (1)
print(type(t1))
# >>>int
t1 = (22.1)
print(type(t1))
# >>>float
t1 = ('李四')
print(type(t1))
# >>>str

t2 = (11,)
print(type(t2))
# >>>tuple
t2 = (11.11,)
print(type(t2))
# >>>tuple
t2 = ('jason',)
print(type(t2))
# >>>tuple

"""
由上面代码可以得到当我们书写可以存储多个数据的类型,并且只有一个元素时,需要在元素后面增加一个,逗号
    (1,)
    [1,]
    {1,}
    {'name':'tony',}
"""

t1 = (1, 2, 3, 4, 5, 6)
# 3.索引取值
print(t1[0])
# >>>1
print(t1[-1])
#>>>6
# 索引取值与列表索引一致

# 4.切片操作
print(t1[1:4])
# >>>(2, 3, 4)
print(t1[-1:-4:-1])
# >>>(6, 5, 4)
print(t1[-4:-1])
# >>>(3, 4, 5)
# 切片与其他基础数据类型一致,可以通过参数进行调整切片的范围与方向

# 5.间隔
print(t1[1:4:2])
# >>>(2, 4)
# 间隔与其他基础数据类型一致,可以通过参数进行调整间隔数

# 6.统计元组内元素的个数
print(len(t1))
# >>>6

# 7.成员运算
print(1 in t1)
# >>>True

# 8.统计某个元素出现的次数
print(t1.count(2))
# >>>1

# 9.元组内元素不能"修改": 元组内各个索引值指向的内存地址不能修改,但是索引里面的是列表之类的可变类型,那么可以进行修改
tt = (1, 2, 3, [1, 2])
print(id(tt[-1]))
# >>>2211858950080
tt[-1].append('5')
print(id(tt[-1]))
# >>>2211858950080
print(tt)
# >>>(1, 2, 3, [1, 2, '5'])

 

  

 

4. 集合的内置方法

# 1. 类型转换
# print(set(11))  # 报错
# print(set(11.11))  # 报错
print(set('tony'))
# >>>{'o', 'n', 'y', 't'}
print(set([1, 2, 3, 4]))
# >>>{1, 2, 3, 4}
print(set({'name': 'tony'}))
# >>>{'name'}
print(set((1, 2, 3)))
# >>>{1, 2, 3}
# print(set(True))  # 报错
# 由此可得,集合中只能转换可变类型,但是集合内元素只能是不可变类型

# 2. 两大功能
# 1. 去重 集合内不能出现重复的元素(自带去重特性)
#   如果出现了 会被集合自动去重
# 2. 关系运算 判断两个群体内的差异
#   如: 共同好友

s1 = {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 3, 2, 2, 1, 2, 3, 2, 3, 4, 3, 2, 3}
print(s1)
# >>>{1, 2, 3, 4}


# 关系运算
f1 = {'jason', 'kevin', 'tony', 'jerry'}  # 李四的好友列表
f2 = {'jason', 'tom', 'jerry', 'jack'}  # 王五的好友列表
# 1.求两个人的共同好友 &
print(f1 & f2)  
# >>>{'jerry', 'jason'}

# 2.求李四的单独好友 -
print(f1 - f2)  
# >>>{'kevin', 'tony'}

# 3.求两个人所有的好友 |
print(f1 | f2)  
# >>>{'kevin', 'jack', 'tom', 'jason', 'jerry', 'tony'}

# 4.求两个人各自的好友 ^
print(f1 ^ f2)  
# >>>{'jack', 'tony', 'tom', 'kevin'}

 

 

5. 垃圾回收机制

"""python底层针对空间的申请和释放都是设计好的 不需要程序员操心"""
1.引用计数
Python垃圾回收主要以引用计数为主,分代回收为辅。引用计数法的原理是每个对象维护一个ob_ref,用来记录当前对象被引用的次数,也就是来追踪到底有多少引用指向了这个对象,当发生以下四种情况的时候,该对象的引用计数器+1

对象被创建  a=14
对象被引用  b=a
对象被作为参数,传到函数中   func(a)
对象作为一个元素,存储在容器中   List={a,”a”,”b”,2}

2.标记清除
    针对循环引用的情况:我们的程序不再使用这些节点对象了,所以我们希望Python的垃圾回收机制能够足够智能去释放这些对象并回收它们占用的内存空间。但是这不可能,因为所有的引用计数都是1而不是0。Python的引用计数算法不能够处理互相指向自己的对象。你的代码也许会在不经意间包含循环引用并且你并未意识到。

3.分代回收
    Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。

 

  

posted @ 2022-03-10 17:53  thrombus  阅读(51)  评论(0)    收藏  举报