本文引用至: python基础类型之dict&sethtml
在python中, 将数据结构分类了两种,一种是序列(sequence), 另一种是字典(dictionary). 其中,序列也就是咱们前面所说的 list and tuple. 字典就是这里将要说的两种-- dict and set
前面介绍了,list && set. 这里,咱们就来探讨一下剩余两个datatypespython
dict 打个比方就至关于 js中的对象. 他实际就是一种散列表(hash)的形式. dict 中的内容是无序的, 但每个值都是以key/value形式出现, 因此当咱们须要查找值时, py会直接根据你调用的key来进行索引,最后返回你的值. 他的查找速度是极快的, 复杂度就是O(1)
而相应的损耗就是内存空间, 因此这也符合hash表的特征, 速度快, 空间大. 经过时间换空间的方式,进行索引.
ok, 如今咱们来建立一个dict:web
>>> my_dict = {1: 'apple', 2: 'ball'} //key, 咱们也是能够换的 >>> new_dict = {'name':'jimmy','age':18} // 访问只能使用key >>> new_dict['age'] 18
实际上, dict就这么简单. 可是, 咱们须要理解他和list的不一样, 因为他的feature 是速度快, 空间大,便于查找. 因此这种方式也经常使用于, 数据存储和传输那一块.
那,有没有什么办法能 convert dict to list呢?
absolutely.
直接使用 list方法便可json
>>> my_dict {1: 'apple', 2: 'ball'} >>> list(my_dict) [1, 2]
不过这样的现实意义并不大, 由于,实际上,他只会截取你dict中的key 做为list的value.
可是, list是不能直接转换为dict的, 除非你是结合元组进行使用.网络
>>> my_dict = dict([(1,'apple'), (2,'ball')]) >>> my_dict {1: 'apple', 2: 'ball'}
最后咱们能够总结一下就是:数据结构
一样无外乎就是CRUD。 这里咱们慢慢讲.app
这里很容易理解, 即就是给dict添加新的内容. 不像, list中有关序列的append,extend,insert方法. 在dict中,只提供了setdefault(key[,value]),update([other]) 进行相关的添加操做.less
setdefault(key[,value]): 用来向dict中指定添加相应的序列. 若是不存在,则新增. 若是存在 则该次添加默认无效, 而且返回已经存在的值. 实际上,这个方法,真的颇有用. 当咱们须要判断一个值是否存在,再添加时,就会用到该方法curl
>>> my_dict {1: 'apple', 2: 'ball'} >>> my_dict.setdefault(1,[2,3]) 'apple' //若是不存在则默认添加 >>> my_dict.setdefault(3,1) 1
update([other]): 该方法是用来批量加入dict。 other的类型能够为dict, 也能够为tuple+list. 咱们看一下官方给的答案:函数
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
上面那段话和keys方法扯上关系了. 实际上,keys是dict的方法. 因此就表明的着dict的类型. 若是你没有keys 方法, 这里就至关于使用for...in... 遍历数据结构,而能这样遍历的, 就只有tuple+list. 看个demo:
>>> my_dict.update({1:2,3:4}) // 直接添加dict, 没问题吧. 继续 >>> my_dict.update([(5,1)])
就酱. 另外,提醒一点,除了setdefault方法之外的其余方法,默认都会覆盖原有的key/value pair.
这里dict 提供了大概4种方法: pop,popitem,del, clear. 咱们分开来讲一下:
pop(k[,d]): 要知道,dict 不一样于dict 是没有顺序的. 若是你的pop不带参数, 那就不能怪谁了, please go die. 全部pop的用法就是, 在dict中删除指定的k, 另外你也能够带上,d(就是value). 若是dict中的k不存在的话, 该方法就会返回d, 不然直接返回删除值.
//指定key删除 >>> my_dict.pop('age') 27 // 因为,ket->age已经被删除了, 这里咱们使用补充的value做为备用,以防出错. >>> my_dict.pop('age',12) 12 //直接返回实现设好的12
popitem(): 这个方法,就不用任何参数了, 他的做用就是,从你的dict中随便删除一个pair,并以tuple的形式返回. 但,若是dict已是empty, 那么就 go die了.
>>> my_dict.popitem() ('name', 'Ranjit')
del : del 在这里 就和list是同样的了. 用来删除指定的值.
>>> del my_dict['age']
clear(): 不说了, 就是清空的意思
在list中,咱们获取部分元素 直接使用分片就行了, 或者大不了使用copy呗. 但在dict中就没有这么方便了.
因此, 为了弥补这个defect, dict提供了几个比较好的方法.
有: fromkeys(seq[, v]),get(key[,d]),copy(),items(),keys(),values()
莫急,咱们慢慢看
fromkeys(seq[, v]): 该方法,实际上就是提取公因式, 用来给不一样的keys 使用同一个val. 生成一个新的dict. 因此,这也引出了下文会提到的comprehension.
>>> dic = dict.fromkeys([1,2,3],12)
get(key[,d]): 相比,直接经过dict[xx]访问方式而言, 我以为这个方法,真的没有什么用. 比较好的也是他的一个判断, 当key不存在值,他不会报错,而且若是你设置好了d,那么不存在的话,就会返回d.
>>> my_dict.get('name') 'Ranjit' // 不存在jimmy的key >>> my_dict.get('jimmy','sexy') 'sexy'
copy(): 不说了, 就是所有复制
items(): 用来返回,dict_items的类型. 他的形式就至关于tupe+list
>>> my_dict.items() dict_items([('name', 'Ranjit'), ('address', 'Downtown')])
只是他的类是dict_items
>>> type(my_dict.items()) <class 'dict_items'>
keys(): 以dict_keys的形式返回dict中的键值.
>>>my_dict.keys() dict_keys(['name', 'address'])
values(): 一样, 以dict__values的形式,返回value值.
>>> my_dict.values() dict_values(['Ranjit', 'Downtown'])
最后,说一下最后3种类型, dict_items,dict_keys,dict_values. 到底干吗的.
官方解释是, 这些至关于只是一个快照(view). 并不会持续存在,这样作的目的就是为了节省内容. 并且,若是你想将两个 dict进行比较的时候, 实际上,只要比较他的dict.values,dict.keys 或者, dict.items 是否相同便可. 由于,这样比较快.(不过,因为无序,你也能够直接比较)
>>> dic.items() == my_dict.items() True
另外,若是你想讲keys或者values保留下来,能够直接使用list方法进行转义便可.
>>> list(dic.values()) ['jimmy', 'Downtown']
最后再补充一下关于dict的 周边方法.
这个和list类型,用来迅速生成一个dict
>>> squares = {x: x*x for x in range(6)} >>> squares {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
只要后面是一个能够遍历的数据结构就行.
另外, 使用for...in... 遍历dict, 他的结果是遍历当中的key 而不是, value.
>>> for x in squares: ... print(x)
dict 在python中叫作字典, 而在js中 叫作对象. 将对象字符串化, 就是JSON的实质.
实际上, 这种格式,是很是利于网络传输的. 如今, 大部分web传输方式都是使用JSON (JavaScript Object Notation)格式, 而上面的书写方式, 只须要转为json便可。
py 提供了咱们一个json的模块, 里面有一些基本方法,最经常使用的,要算dumps和loads.
作个类比:
dumps: 至关于js中的JSON.stringify()
loads: 至关于js中的JSON.parse()
来具体看看方法参数吧:
loads(s, encoding=None[,...]): 实践上,这是loads提供的参数配置, 通常而言, 咱们只须要默认参数便可. 使用方法很简单:
>>> json_str '{"shares": 100, "name": "ACME", "price": 542.23}' >>> json.loads(json_str) {'name': 'ACME', 'shares': 100, 'price': 542.23}
对比一下,引号应该就知道其中的意义了.
dumps(obj[,..]): 一样,dumps 咱们使用默认参数便可. 用来将obj 转化为str.
>>> data {'shares': 100, 'name': 'ACME', 'price': 542.23} >>> json.dumps(data) '{"shares": 100, "name": "ACME", "price": 542.23}'
一样,你们比较一下就知道了.
另外, 这里须要说起几点的是: 在和JSON相互转化的过程当中, FalseTrue converted to false/true. None -> null. 另外json 中还提供了 load,dump方法,用来对文件进行操做. 有兴趣的同窗,能够参考一下官方文档: json
来看张总结图谱吧
这里,想要介绍一个, 专门为数学运算准备的数据结构--set. set不一样于dict, 他没有成对的key/value。 他只会包含,不重复的value. 一个简单的set,咱们能够这么写
>>> s = {1,2,3,4} // 若是你要建立空的set的话, 请使用set()方法. >>> s = set() // 否则的话, 就是dict类型了
就是讲你所须要的值放在 curly braces里面便可.
咱们来看看他最重要的feature--不重复
>>> s = {x for x in [1,1,1,1]} >>> s {1}
另外, set是不能包含mutable datatype. 好比 list。(tuple 能够)
>>> s = {[1,2,3]} TypeError: unhashable type: 'list' // 已经给出, 不能存放非 hash 值
实际上, set还有一个很重要的做用,就是用来 remove duplicates. 特别针对于list
使用方法就是直接使用set()进行过滤便可. 咱们能够定义一个函数unique
def unique(l): l = set(l) l = list(l) return l >>> unique([1,1,1]) [1]
那么,咱们怎么访问set呢?
孩纸, 对不起,
一样, set和dict类型, 也存在CRUD操做, 不过,他还自带了innate buffer. 集合运算
py提供了两个方法, 一个是add, 一个是update.
add(ele): 该方法,用来添加一个ele. 但若是该ele存在, 那么该次添加就是useless
>>> new_set {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} >>> new_set.add(10)
update(iterable): 该方法用来添加多个set元素. 参数必须是能够遍历的.好比,list,set,tuple,dict. 固然,若是是dict的话, 他只会添加key进去
>>> new_set.update({'a':1,'b':2}) {'a','b'}
在set中, 一样提供了几个可供处理的方法: discard,remove,pop,clear.
discard(ele)和remove(ele) 其实是有点相像的. 惟一的difference是, 使用discard时, 若是元素不存在,不会报错,而remove会.
>>> my_set {1, 3, 5} >>> my_set.discard(2) >>> my_set {1, 3, 5} >>> my_set.remove(2) KeyError: 2
那set不是无序的吗? 为何会有pop这个方法呢?
对比与dict 中的popitem方法而言, 在set中,pop就已经能够表明这个意思了. 即, 使用pop()方法,会随机删除 set中的某一个值.而且会返回删除的值. 若是为空的话,会报错
>>> new_set {0, 1, 2} >>> new_set.pop() 0
clear就是清空的意思,就酱.
对于list有tuple, 而set 对应的immutable datatype就是 frozenset. frozenset实际上就是 固定的set. 因此, 对于create 和 delete 方法而言是不能应用在frozenset上的. 那frozenset该怎么玩呢?
定义一个frozenset, 能够直接使用frozenset() 方法.
frozenset(iterable): 它里面接受能够进行遍历的datatype, 上面所说的 set,list等都行
>>> A = frozenset([1, 2, 3, 4]) >>> A frozenset({1, 2, 3, 4})
那咱们何时会使用到呢?
表问我, 我也母鸡. 看心情吧
接下来,才应该是set的重头戏, 集合操做.
简单的结合操做无外乎: 交(&),并(|),差(-),对称差(^). 简单的还有包含(⊆),真包含(⊂).
咱们先来看几个容易理解的:
两个集合相并:
在python中, 咱们可使用|
operator。 或者是union()方法
>>> A | B {1, 2, 3} >>> A.union(B) //等价于 >>> B.union(A)
还记得, 并的对称性吧. A|B = B|A
两个集合相交:
在python中, 咱们就可使用 &
表达式, 或者 intersection方法,来作.
>>> A & B {4, 5} >>> A.intersection(B) {4, 5} >>> B.intersection(A) {4, 5}
两个集合的差集:
在python中, 咱们就可使用-
或者difference()方法来表示
>>> A - B {1, 2, 3} >>> A.difference(B) {1, 2, 3}
这个就是上图的表达式
两个集合的对称差 [(A-B)∪(B-A)]:
在python中,表达可使用^
或者symmetric_difference()方法.(你以为那个简单?)
>>> A ^ B {1, 2, 3, 6} >>> A.symmetric_difference(B)
上面两个就是两个集合的基本操做. 而且衍生出另一个set. 在python的set操做中, 还有判断两个集合是否相关的方法: isdisjoint(),issubset(),issuperset().
如今假设有集合A和集合B。
>>> B {0, 1, 2, 3} >>> A {0, 1, 2}
isdisjoint(): 判断两集合是否相交. 记住, 包含并非相交, 相交是指有一部分包括,有一部分不包括, 至关于就是两个圆外边界相交
>>> A.isdisjoint(B) //两个的关系是包含的意思 False >>> A.issubset(B) True
A.issubset(B): 判断集合B是否包含集合A. 固然, 彻底相等也算包含. 实际上就是数学中的⊆.
A.issuperset(B): 判断集合A是否包含集合B。 这里我就不绕了, 你们看状况使用便可.
>>> A.issubset(B) True >>> A.issuperset(B) False
另外, 咱们检查一个元素是否在另一个set中,能够直接使用 in
关键字了.
看个demo.
>>> A {0, 1, 2, 3} >>> 1 in A True
到这里, set的基本内容,应该差很少了. 剩下的就是在实践中,不断磨练了.
看个总结图: