python (7) 数据结构2 字典and集合

字典

是一个映射类型的数据结构
1.每个字典中的元素都是一对键值对
2.字典称为dict;键称为key;值称为value {"key":value}
3.字典不可以有相同的key但可以有相同的value

1.创建字典

创建方法为变量名={}

>>> d1 = {}    #创建空字典,
>>> type(d1)
<type 'dict'>
>>> d1
{}

>>> d1 = {"key":2}    #创建含有单个的
>>> type(d1)
<type 'dict'>
>>> d1
{'key': 2}

字典中元素是无序的
即你输入的字典和你再次输出的字典的顺序可能是不一样的
如:
d2 = {'shark': '鲨鱼', 'qf': '千锋'}
d2
>>>{'qf': '千锋', 'shark': '鲨鱼'}
#但是在我的实验中输出的和我输入的是一样的,不知道是不是改版的原因

2.dict()其他的数据类型转换成字典

>>> d_tp1 = [['a','1'],['ss','1']]    
#注意,列表是不能作为字典的值或者键的,但是如果在未定义字典之前不算,
#即上面的可以这样写的原因是因为我们需要将列表变为字典,这只是个转换
>>> dict1=dict(d_tp1)   
>>> dict1
{'a': '1', 'ss': '1'}

>>> d_tp1 = [('a','1'),('ss','1')]
>>> dict1=dict(d_tp1)       
 #把这个数列转换成字典;但必须是一对的;因为必须有键还有值
>>> dict1
{'a': '1', 'ss': '1'}
>>> d_tp2= ['ab','bc']     #可以看成两个字符串
>>> dict2=dict(d_tp2)
>>> dict2
{'a': 'b', 'b': 'c'}

3.zip()并行迭代

  • 会停在最短的序列
>>> who=['tom','jan','kity']
>>> age=['17','18','16','19']    #下面的19没有继续取出
>>> for name , old in zip(who,age):      
...     print(name, old)
... 
tom 17
jan 18
kity 16
>>> for name , age in zip(who,age):
...     print(name ,old)
... 
tom 17
jan 18
kity 16
==============================
利用 zip() 函数可以对具有相同数量的元素的序列进行配对;
返回的值不是元组,也不是列表,而是一个整合在一起的可迭代变量。
>>> who=['tom','jan','kity']
>>> age=['17','18','16','19']
>>> zip(who,age)
<zip object at 0x7fbccada04b0>
>>> type(zip(who,age))
<class 'zip'>
>>> list(zip(who,age))
[('tom', '17'), ('jan', '18'), ('kity', '16')]
>>> dict(zip(who,age))
{'tom': '17', 'jan': '18', 'kity': '16'}

4.哪些数据可以作为字典的key

key 通常是 字符串

它可以是 Python 中任意不可变类型

比如:

布尔型 True 1 False 0
整型 100 200
浮点型 1.0; 3.415
元组 (1,) (1, 2, 3)
字符串 'host_name'
关于字典的 key

哈希是指一个过程,这个过程就是把任意长度的输入,通过哈希算法,变换成固定长度的输出,所输出的称为哈希值。这种变换是一种压缩映射,也即哈希值所占的空间一般来说远小于输入值的空间,不同的输入可能会哈希出相同的输出(概率很小)。

在 Python 内部用一个哈希表来维护字典中的 key 到 value 的映射关系。
所以 key 必须是可哈希的。dong
判断一个对象是否可哈希,可以使用 hash() 函数
返回一个整数,就是可哈希,反之会抛出 TypeError 异常

>>> hash(1)
1
>>> hash('name')      #字符串可以被哈希
-5658134882158534392
>>> hash(('1',2))       #元组也可以被哈希
8438592034789701679
>>> hash(['1',2])       #列表不能被哈希
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash({'1',2})       #集合不能被哈希
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> hash(('1',2))
8438592034789701679

5.get()得到单个值

  • 它的那个get(‘键’,'返回值')非常的有用
>>> dict_obj = {'a':1,'b':2}
>>> dict_obj['a']
1
>>> dict_obj['c']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'c'
---------------------------
>>> dict_obj.get('a')       #输入键名才有用
1
>>> v=dict_obj.get('a')      
>>> v
1
>>> v=dict_obj.get('c')
>>> v
>>> type(v)
<class 'NoneType'>
>>> v=dict_obj.get('c','worry')     
#当存在c这个键的时候就会输出value,如果没有c这个键的时候就会输出后面的worry字符串
>>> v
'worry'
>>> type(v)
<class 'str'>

实例

>>> info_dict={"name":'yangge','age':18}
>>> na=info_dict['name']        
>>> print(na)
yangge
>>> naa =info_dict.get('age')   
>>> print(naa)
18
>>> naa = info_dict['dd']     #没有的键取值会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'dd'
>>> age2=info_dict.get('asdf')  
>>> print(type(age2))         #没有age2 所以也无从说类型
<class 'NoneType'>    
>>> print(type(age2),age2)     没有age2键,无法取值
<class 'NoneType'> None
>>> age3 = info_dict.get('adaf', '')
>>> print(age3)
                                                        #没有adaf这个键,所以输出为空值''
>>> print(type(age3))                #空值的类型为字符
<class 'str'>
>>> print(type(age3),'')   
<class 'str'>                               输出类型加''
>>> age4 = info_dict.get('adaf', 28)      #没有adaf这个键就输出28
>>> print(type(age4),age4)           28为整数
<class 'int'> 28


6.得到所有的键keys()

>>> dict_obj = {'a':1,'b':2}
>>> dict_obj.keys()         #只取得键
dict_keys(['a', 'b'])    
#可迭代对象,还没展开,节省内存;而python2展开了为['a', 'b'],如果python2 想得到可迭代对象那么就要iterkeys()

>>> for k in dict_obj.keys():             #取得键的方法1
...     print(k)
... 
a
b
>>> for k in dict_obj:                       #取得键的方法2
...     print(k)
... 
a
b

7.获取字典的值values()

dict_obj.values()

info_dict = {"name":"yangge","age":18}
dict_values = info_dict.values()
print(dict_values)
   #这只能去多个的值,如果想取单个的可用get(键)
输出>
dict_values(['yangge', 18])

8.同时获取字典的键和值

dict_obj.items()

>>> dict_obj={'a':1,'b':2}
>>> 
>>> item=dict_obj.items()
>>> print(item)
dict_items([('a', 1), ('b', 2)])   #分别取了值不再是字典的形式了
---------------------------------------------
>>> for item in dict_obj.items():     #循环取值
...     print(item)
...    
... 
('a', 1)
('b', 2)

>>> for k,v in dict_obj.items():     
...     print(k,v)
... 
a 1
b 2    #可以自动解包了

info_dict={"name":'yangge','age':18}
for k,v in info_dict.items():
... if k == 'age':
... d6["age_o"] = v
>>> d6
{'age_o': 18}

9.使用=修改或更新字典

可以使用 等号 对字典的 key 进行直接赋值操作。

  • 假如 key 不存在与字典中,这个 key 和 对应值也会被创建到字典中。
  • 如果存在这个key那么覆盖这个值;多次覆盖只显示最后一次覆盖之后的值
单个单个的赋值
In [50]: d5 = {}

In [51]: d5['a'] = 1

In [52]: d5['b'] = 2

In [53]: d5
Out[53]: {'a': 1, 'b': 2}

In [54]: d5['li'] = [1,3,5]

In [55]: d5
Out[55]: {'a': 1, 'b': 2, 'li': [1, 3, 5]}
-----------------------------------------
In [68]: d5 = {'a': 1, 'b': 2, 'li': [1, 3, 5]} 

In [69]: d6 = d5

In [70]: d6 is d5
Out[70]: True

In [71]: d7 = d5.copy()

In [73]: d7 is d5
Out[73]: False

In [74]: d7 == d5   # 双等号 是用来判断 等号两边的对象的值是否相等
Out[74]: True

在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,
分别是:id(身份标识)、type(数据类型)和value(值)。
is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。下面来看看具体区别在哪。
==比较操作符和is同一性运算符区别
1.==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等:
2.is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。通过对下面几个list间的比较,你就会明白is同一性运算符的工作原理:

10.更新update()

  • 注意:如果更新的key一样就会覆盖原来可以的值 。用来赋值也是可以的
>>> d6 = {'a': 2,'d': 2,'e': 5}
>>> d5={'a':1,'b':2}
>>> d5.update(d6)      #就是找出6中与5不同的,然后把不同的加入到d5中
>>> d5
{'a': 2, 'b': 2, 'd': 2, 'e': 5}

>>> info_dict
{'age': 18, 'name': 'yangge'}
>>> d7 = {'a':1}
>>> info_dict.update(d7)
>>> info_dict
{'age': 18, 'name': 'yangge', 'a': 1}

11.判断成员 in

判断key的时候可以不写key()
但是判断value的是时候要加value()

>>> d5
{'a': 2, 'b': 2, 'd': 2, 'e': 5}
>>> 'a' in d5         #可以不写key因为默认用key匹配
True
>>> 'a' in d5.keys()
True
>>> '2' in d5.values()     #‘2’是字符串
False
>>> 2 in d5.values()
True

12.清空和删除字典

1)del删除特定的的键值对或者全删

删除单个
>>> d5
{'a': 2, 'b': 2, 'd': 2, 'e': 5}
>>> del d5.key('a')
>>> del d5['a']     #注意这个写法。和取值是一样的
>>> d5
{'b': 2, 'd': 2, 'e': 5}
删除字典
>>> d5
{'b': 2, 'd': 2, 'e': 5}
>>> del d5
>>> d5            # 删除字典本身,字典自身就不存在于内存中了
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'd5' is not defined

del适用于python的所有对象;不会返回值

2)清空clear()
dict_obj.clear() # 字典本身还在内存中,只是内容没了

3)删除特定的键值对pop()
从字典中删除指定 key 的键值对,并返回这个 key 对应的值 ;括号内不能不输入
返回的的

>>> d6 = {'b': 2, 'c': '3', 'd': 'new key', 'li': [1, 3, 5]}
>>> 
>>> li = d6.pop('li')
>>> print(li)
[1, 3, 5]
>>> d6
{'b': 2, 'c': '3', 'd': 'new key'}

popitem()
删除字典中的键值对,并返回这个键和值 ;默认删除最后一个

>>> d6 = {'b': 2, 'c': '3', 'd': 'new key', 'li': [1, 3, 5]}
>>> item = d6.popitem()     
>>> print(item)
('li', [1, 3, 5])
>>> print(d6)
{'b': 2, 'c': '3', 'd': 'new key'}

练习
d6={'b': 2, 'c': '3', 'd': 'new key','li', [1, 3, 5]}
item = d6.popitem()

print(item)
print(d6)

"""答案
('li', [1, 3, 5])
{'b': 2, 'c': '3', 'd': 'new key'}
"""

扩展知识: setdefault 处理缺失的键

  1. key 不存在,添加 key: value 到字典中,并且返回字典中的 value 对象,也就是说返回的 value 和刚添加到字典中的 value 是同一个对象 ;
  2. key 存在, 返回对应的 value,原字典不变
>>> obj.setdefault('ala',[])       #没有ala所以会添加到字典中
[]
>>> obj.setdefault('ala',[]).append('s')      #这是一个延伸的
>>> obj
{'ala': ['s']}
>>> obj.setdefault('ala',[]).append('by')   #这样就可以加入多个数列 的值
>>> obj
{'ala': ['s', 'by']}

扩展知识

f={True: 'yes', 1: 'no', 1.0: 'maybe'}    #True的值=1=1.0 ,所以会覆盖赋予key“True” 的值
date=['no', 'yes'][True]       #这个True是索引号1的意思
print(f)
print(date)

{True: 'maybe'}
yes

集合

1 集合特性介绍

集合本身也不能被哈希
集合不能包含有相同的元素

在 python 中集合看起来像是只有 key 的字典

{'disk','cpu','memory','motherboard'}

在 python 解释器中表现为 set()

集合内的元素不允许重复

2.把其他的类型转换成集合set()

创建一个空的集合
d=set()       #用这个而不是{},{}是创建空字典的

 >>>set('disk')
 {'d', 'i', 'k', 's'}

 >>>set(['disk','cpu','memory'])
 {'cpu', 'disk', 'memory'}

 >>>set(('disk','cpu','memory'))
 {'cpu', 'disk', 'memory'}

 >>>set({'disk': '560G','cpu': '4'})
 {'cpu', 'disk'}

3.添加一个元素add()

>>>s2 = {12,3,4,5,6,}

>>>s2.add('n')

>>>s2
{12, 3, 4, 5, 6, 'n'}

4.删除一个元素remove()

>>>s2.remove('n')

>>> s2
 {4, 5, 6, 12}

5.随机干掉一个元素pop()

s2 = {12,3,4,5,6,}
print(s2.pop())

输出>3

6.集合的运算
a.交集$ :获取 两个集合都含有的
b.并集| :获取两个集合加起来的
c.差集-:获取第一个集合中独有的
d.异或运算^:获取两个集合中分别独有的元素,组合成一个新的集合

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容