一. 浅拷贝和深拷贝
 
浅拷贝:就是创建一个具有相同类型,相同值但不同id的新对象。 
浅拷贝产生的新对象中可变对象的值在发生改变时,会对原对象的值也做出改变,因为这些值是同一个引用。
a = [1, 2]
b = [3, 4, a]
c = b.copy()
a[0] = 0
print(b)
print(c)
输出
[3, 4, [0, 2]]
[3, 4, [0, 2]]
 
 
深拷贝:不仅仅拷贝了原始对象自身,也对其包含的值进行拷贝,它会递归的查找对象中包含的其他对象的引用,来完成更深层次拷贝。
深拷贝产生的副本可以随意修改而不需要担心会引起原始值的改变
import copy
 
a = [1, 2]
b = [3, 4, a]
c = copy.deepcopy(b)
a[0] = 0
print(b)
print(c)
输出结果
[3, 4, [0, 2]]
[3, 4, [1, 2]]
 
 
 
 
 
二. dict的常用方法
 
1. fromkeys把可迭代的对象转变为dict
基本语法:dict.fromkeys(可迭代对象作为keys,默认值作为value)
 
new_list = ["name1", "name2"]
new_dict = dict.fromkeys(new_list, 34)
print(new_dict)
输出如下
{'name1': 34, 'name2': 34}
 
 
2. clear,清空字典中数据
a = {"name1": "jack", "name2": "jane"}
print(a)
a.clear()
print(a)
输出如下
{'name2': 'jane', 'name1': 'jack'}
{}
 
 
3. copy(这里是浅拷贝)
a = {"name1": "jack", "name2": "jane"}
print(a)
b = a.copy()
print(b)
 
# 修改a的值后,b也会跟着改变;同样如果修改b,a也会相应改变
a["name1"] = "hong"
print(a)
b = a.copy()
print(b)
输出如下
{'name2': 'jane', 'name1': 'jack'}
{'name2': 'jane', 'name1': 'jack'}
{'name2': 'jane', 'name1': 'hong'}
{'name2': 'jane', 'name1': 'hong'}
 
 
4. get,避免字典中keyerror异常
语法:a.get(键名,默认值)如果字典a中没有某个键名,就返回默认值
a = {"name1": "jack", "name2": "jane"}
value = a.get("name3", "not exist")
print(value)
输出如下
not exist
 
 
5. setdefault(),和get()相似,不同的是如果没有某个键名,会把此键名和默认值加入到字典中
a = {"name1": "jack", "name2": "jane"}
 
# 没有指定键名时
a.setdefault("name3", "not exist")
print(a)
 
# 存在此键名时
b=setdefault("name1", "not exist")
print(b)
输出如下
{'name2': 'jane', 'name3': 'not exist', 'name1': 'jack'}
jack
 
 
6. update(), 可用于添加字典元素
a = {"name1": "jack", "name2": "jane"}
 
# 直接添加字典方式
a.update({"name3": "hong"})
print(a)
 
# 使用参数名方式
a.update(name4="lilei", name5="mei")
print(a)
 
# 使用list嵌套tuple方式,同样的tuple也可以嵌套tuple
a.update([("name6", "tiger"), ("name7", "monkey")])
print(a)
输出如下
{'name2': 'jane', 'name1': 'jack', 'name3': 'hong'}
{'name2': 'jane', 'name1': 'jack', 'name4': 'lilei', 'name5': 'mei', 'name3': 'hong'}
{'name6': 'tiger', 'name1': 'jack', 'name4': 'lilei', 'name3': 'hong', 'name7': 'monkey', 'name2': 'jane', 'name5': 'mei'}
 
 
 
 
 
三. set和frozenset(不可变集合)
 
特点:元素不会重复,无序性,里面的对象需要是可迭代,使用hash方式能很高
frosenset无法使用add函数添加值
 
1. 初始化方法
# 使用set关键字
s1 = set('abc')
 
#使用{}
s2 = {'a', 'b'}
 
print(type(s1), type(s2))
输出
<class 'set'> <class 'set'>
 
2. 添加元素方式
# 使用add()函数
s1 = set('abc')
s1.add('d')
print(s1)  
 
# 使用update()函数
s2 = set('xy')
s1.update(s2)
print(s1)
输出
{'a', 'c', 'd', 'b'}
{'b', 'a', 'x', 'c', 'y', 'd'}
 
3. difference()函数来求两个集合的差集
s1 = set('abc')
s2 = set('cd')
 
# 相当于s1 - s2
re_set = s1.difference(s2)
print(re_set)
输出结果如下
{'b', 'a'}
注意:difference()函数会返回一个新值,不会修改原数据
 
4.  集合的并集,交集
s1 = set('abc')
s2 = set('cd')
# 交集
re_set1 = s1 & s2
# 并集
re_set2 = s1 | s2
print(re_set1, re_set2)
输出结果如下
{'c'} {'c', 'a', 'b', 'd'}
 
5. issubset()判断集合A是否为集合B的子集
s1 = set('abc')
s2 = set('c')
 
print(s2.issubset(s1))
输出结果为True
 
 
 
 
 
 
四. dict和set的内部实现原理
 
1. list和dict的性能比较
1)dict的查找性能远大于list
2)在list中随着list数据量的增大,查找相同数据量的时间也会增大
3)在dict中随着dict数据量的增大,查找相同数据量的时间不怎么受影响
 
 
 
2. hash表数据存储实现图
 
 
1)右侧是hash表的存储结构,是一个数组,使用了一段连续的内存空间
2)字典中的key进行hash计算得到一个hash值,然后和7进行与的位运算后,得到一个值,比如是0,就把dict中的键值对放到0的这个内存位置
3)不同的key进行hash计算后,可能会得到一个相同的hash值,从而造成冲突;为解决这个问题,可按照一种机制重新进行hash计算。
4)声明数组的时候,分配的内存空间会比实际的dict数据量大
5)只须根据dict的key找到数组中的前面的偏移量,即可得到相应的键值对,复杂度为O(1)
 
 
3. 哈希表查找原理图
 
说明:
1)表元就是哈希图中最右侧存储键值对的地方
2)散列冲突就是hash冲突
3)造成散列冲突时,会多取几位散列值来定位表元。
 
 
4. dict原理小结
1)dict的key或者set的值都必须是可hash的,他们的实现原理相同。不可变对象都是可hash的,比如string, tuple, fronzenset
2)dict的内存花销大,但是查询速度快;自定义的类中,只要加上魔法函数__hash__, 那么这个类就是可hash的
3)dict的存储顺序和元素添加顺序有关,因hash值冲突的原因
4)添加数据的时候有可能会改变已有数据的顺序:存储dict的时候,python会预先申请一段大于dict数据需求的连续内存空间,以减少hash冲突的概率,当添加数据量使得大于分配内存空间的1/3的时候,python就会另申请一个较大的内存空间,把原先的数据进行迁移,重新进行hash值的计算
 
 

深入set和dict的更多相关文章

  1. tuple放入dict中

    tuple放入dict中是否可以正常运行 # 将tuple放入dict中 a = ('AI','Kobe','Yao') b = ('AI',['Kobe','Yao']) dict1 = {'a': ...

  2. redis数据结构存储Dict设计细节(redis的设计与实现笔记)

    说到redis的Dict(字典),虽说算法上跟市面上一般的Dict实现没有什么区别,但是redis的Dict有2个特殊的地方那就是它的rehash(重新散列)和它的字典节点单向链表. 以下是dict用 ...

  3. python list dict 去重的两种方式

    def dedupe(items, key=None): seen = set() for item in items: val = item if key is None else key(item ...

  4. list,tuple,dict,set常用方法

    Python中list,tuple,dict,set常用方法 collections模块提供的其它有用扩展类型 from collections import Counter from collect ...

  5. python dict clear只能删除一层,不能够递归删除。

    void PyDict_Clear(PyObject *op) { dictobject *mp; dictentry *ep, *table; int table_is_malloced; Py_s ...

  6. Python中内置数据类型list,tuple,dict,set的区别和用法

    Python中内置数据类型list,tuple,dict,set的区别和用法 Python语言简洁明了,可以用较少的代码实现同样的功能.这其中Python的四个内置数据类型功不可没,他们即是list, ...

  7. python第一天 - dict

    dict key-value集合. d = { ': 'a', ': 'b', ': 'c' } (一).获取集合长度:len(d) = 3(二).获取值: 方式一:d[key];例:d['1'] = ...

  8. python利用dict模拟switch

    pytho本身并未提供switch语句,但可以通过dict来模拟switch, #方法1 def add(x,y): return x+y def dec(x,y): return x-y def m ...

  9. python-list tuple dict set

    1:删除一个列表末尾的元素 pop方法 >>> a [1, 'Jack', 2, 3, 2] >>> a.pop() >>> a [1, 'Jac ...

  10. python基础之dict、set及字符

    python基础之dict.set及字符串处理 本节内容 字典介绍及内置方法 集合介绍 字符串处理 1.字典介绍及内置方法 字典是python中唯一的映射类型,采用键值对(key-value)的形式存 ...

随机推荐

  1. 数据库链接 mybatis spring data jpa 两种方式

    jdbc mybatis                     spring data jpa dao service webservice jaxrs     jaxws  springmvc w ...

  2. 2018.07.04 BZOJ 2823: AHOI2012信号塔(最小圆覆盖)

    2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MB Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握 ...

  3. 2018.09.05 bzoj2726: [SDOI2012]任务安排(斜率优化dp+二分)

    传送门 跟Ti" role="presentation" style="position: relative;">TiTi为正数的时候差不多. ...

  4. bootstrap模态框的调用

    1.<a href="JavaScript:void(0);" class="bs-tooltip remark-item" rel="{$bi ...

  5. hdu-1050(贪心+模拟)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1050 思路:由图可知,1对应2,3对应4,以此类推,如果x,y是偶数则变为奇数: 每次输入两个区间,找 ...

  6. gj2 python中一切皆对象

    2.1 python中一切皆是对象 动态语言和静态语言的区别,Python的面向对象更彻底 同时动态语言,代码的灵活性高 没有编译(检查)的过程,错误只有在运行起来后才会发现 函数和类也是对象,属于p ...

  7. Can not find the tag library descriptor for "/struts-tags"`

    1.查看struts.xml路径是否错误,要放在src下, 2.缺少struts-tags.tld (1)查找方式: (2)找到此包,然后右键用解压缩文件打开. (3)然后你会看到很多的源码,找到红圈 ...

  8. jersey学习笔记

    最近一个项目用到了jersey,我只是负责前端.也借此机会好好了解一下REST webservice及一大推名词. http://redhacker.iteye.com/blog/1914105 1. ...

  9. mysql中设置默认字符编码为utf-8

    使用过Linux的同志就知道,在Linux下安装mysql,尤其是使用yum安装的时候,我们是没法选择其默认的字符编码方式.这个就是一个比较头痛的问题,如果Linux数据库中使用到中文的时候,乱码问题 ...

  10. 【PAT Advanced Level】1014. Waiting in Line (30)

    简单模拟题,注意读懂题意就行 #include <iostream> #include <queue> using namespace std; #define CUSTOME ...