鱼C论坛

 找回密码
 立即注册
查看: 1206|回复: 0

[技术交流] 【四】数据结构2:字典和集合

[复制链接]
发表于 2021-9-15 17:48:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Python初学者8号 于 2021-9-22 09:25 编辑

2021年9月15日17:48:39
小甲鱼也是分开讲的,这个数据结构有点区别。主要在于不是用数字index来索引的,是一种二元的具有映射关系的特殊的数据结构。
我寻思这个和之前的sequence的区别主要还是数据结构的底层吧,当然还是根据需要来的。这个有点像是C中的那个“结构体”?
总之字典的特点就是具有映射关系的二元数组

字典
顾名思义,这个名字已经很形象,就是一个字符(或者是一个不可变对象)对应一个内容(value)
1.定义
按照形式来 :键 —— 值
  1. dictionnary = {key1 = values1 , key2 = values2, key3 = values3 , key4 = values4, key5 = values5}
复制代码

2.创建
创建方式同sequence那样,符号和函数两种方式
符号就是{}函数是,dict()。这个方法很好用,根据字典的二维映射数组的特点可以有这几种方法创建
2.1 定义法
  1. a={'a': 1, 'b': 2, 'c': 3, 'd': 4}
复制代码

2.2 赋值法
  1. a= dict(a = 1, b =2, c=3, d=4)
复制代码
注意千万不能是加上了引号。其实这个才是最方便直接打出一个随意的字典的,因为按照定义的来话就很麻烦
  1. >>> a = dict(<font color="#ff0000">'</font>a<font color="#ff0000">'</font>=1,'b'= 2,'c'= 3,'d'= 4)
  2.   File "<pyshell>", line 1
  3. SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
复制代码

2.3 二维序列法
或者是二维列表,或者是二维的元组。
  1. >>> c = dict([('abandon',1),('adam',2),('alex',3),('ape',4)])
复制代码
  1. >>> b= dict((('abandon',1),('adam',2),('alex',3),('ape',4)))
复制代码
注意,这是要加引号的!
  1. <font color="#ff0000">不加引号就出错</font>
复制代码

2.4 zip()方法
是这个方法也是一种映射啊,和字典很相似了其实,
  1. <font color="#ff0000">先定义一个zip对象</font>
  2. >>> z1=('we','will','rock','you')
  3. >>> z2 = (1,2,3,4)
  4. >>> z3 = zip(z1,z2)
  5. >>> z3
  6. <zip object at 0x000001C1F339E400>
  7. >>> for i in z3:
  8.     print (i)
  9.    
  10. ('we', 1)
  11. ('will', 2)
  12. ('rock', 3)
  13. ('you', 4)
复制代码
然后再来
  1. >>> d = dict(z3)
  2. >>> d
  3. {}
  4. >>> d = dict(zip(z1,z2))
  5. >>> d
  6. {'we': 1, 'will': 2, 'rock': 3, 'you': 4}
复制代码
我们可以看到,很明显,d = dict(z3),这是错的,这是因为这z3只是单个元素,他不像是二维列表和元组那样直观的可以显示,他应该是一种更加复杂的数据结构吧?
2021年9月16日09:55:54更正上面的说法,实际上来说,dict(z3)是可行的,为什么不可行,可能是和我在shell中运行有关吧还有一个必须指出的是,zip不仅仅可以映射一对数据,可以映射好几对!!就像是矩阵或者是数表一样!!估计这样才是他不能像是字典一样显示的原因吧?
  1. z1=('we','will','rock','you')
  2. z2 = (1,2,3,4)
  3. z3 = ('one','two','three','four')
  4. z = zip(z1,z2,z3)
复制代码
  1. >>> z
  2. <zip object at 0x000002E95F2F6780>
  3. >>> for i in z:
  4.     print(i)
  5.    
  6. ('we', 1, 'one')
  7. ('will', 2, 'two')
  8. ('rock', 3, 'three')
  9. ('you', 4, 'four')
复制代码
并且,这里还要插一嘴提到了迭代器的一些特点
  1. >>> z1=('we','will','rock','you')
  2. >>> z2 = (1,2,3,4)
  3. >>> z3 = zip(z1,z2)
  4. >>> d = dict(z3)
  5. >>> d
  6. {'we': 1, 'will': 2, 'rock': 3, 'you': 4}
  7. >>> for i in z3:
  8.     print(i)
  9.    
  10. >>> d
  11. {'we': 1, 'will': 2, 'rock': 3, 'you': 4}
  12. >>> e = dict(z3)
  13. >>> e
  14. {}
复制代码
逃兵 发表于 2021-9-16 10:10
迭代器就像枪里的子弹
按照你上膛的顺序(有序)
打一发少一发(有量)

总结:还是赋值法在自己随意创建的时候最简单,因为不用写引号;     如果是像是电话本那样的话,还是二维序列法简单:  如果是两个同纬度向量就是选择zip咯!!!看看官方文档
|  dict() -> new empty dictionary
|  dict(mapping) -> new dictionary initialized from a mapping object's
|      (key, value) pairs
|  dict(iterable) -> new dictionary initialized as if via:
|      d = {}
|      for k, v in iterable:
|          d[k] = v
|  dict(**kwargs) -> new dictionary initialized with the name=value pairs
|      in the keyword argument list.  For example:  dict(one=1, two=2)

3.访问
不再是index,而是key访问,方法很像,就是dic[key]

还有一种方法,针对dic[key]的问题来的:dic[key]的问题在于如果找不到回报错出来KeyError。有些场合为了不报错就可以用这个get()方法

get()方法也是参数为key,找不到就是直接给出一个默认值,而这个默认值可以修改的(默认参数哦!!
  1. <blockquote>>>> d
复制代码
  1. >>> d.get('2','没有啊大哥!!!')
  2. '没有啊大哥!!!'
  3. >>> type(d.get('2','没有啊大哥!!!'))
  4. <class 'str'>
复制代码

当然同样可以使用in 还有 not in 的方法来间接查询
  1. >>> '2' in d
  2. False
复制代码


4.运算
包括添加,删除,修改,
  1. >>> d
  2. {'we': 1, 'will': 2, 'rock': 3, 'you': 4}
复制代码
添加可以直接使用dic[新的keys] = 新的value;或者是使用update()方法
  1. >>> d['!']=5
  2. >>> d
  3. {'we': 1, 'will': 2, 'rock': 3, 'you': 4, '!': 5}
复制代码
如果想添加很多个的话,就像extend列表一样,可以使用update方法。
  1. >>> a.update(("e",5))
  2. Traceback (most recent call last):
  3.   File "<pyshell>", line 1, in <module>
  4. ValueError: dictionary update sequence element #0 has length 1; 2 is required
  5. >>> a.update("e",5)
  6. Traceback (most recent call last):
  7.   File "<pyshell>", line 1, in <module>
  8. TypeError: update expected at most 1 argument, got 2
复制代码
  1. <font color="#ff0000">该方法的参数只有一个,是个字典(这点和extend 的列表方法是一样的)</font>
  2. [code]>>> ls.extend([111,222])
  3. >>> ls.extend(111,222)
  4. Traceback (most recent call last):
  5.   File "<pyshell>", line 1, in <module>
  6. TypeError: extend() takes exactly one argument (2 given)
复制代码
正确的方法是这个,并且其id不会变哦!!同样的,同extend一样,这两个修改方法本身并没有返回值
  1. <font color="#ff0000">>>>d.update({'!':5})</font>
复制代码

删除就是直接del dic[keys]
  1. >>> del d['!']
  2. >>> d
  3. {'we': 1, 'will': 2, 'rock': 3, 'you': 4}
复制代码
修改就直接赋值就可以了  dic[keys] = value;            必须指出的是,key是不可修改的!!!我想将you改为U就不行,只能新建一个!!这个点字典时介于列表的可变性和元组的不可变性之间的
  1. >>> d['you']=100
  2. >>> d
  3. {'we': 1, 'will': 2, 'rock': 3, 'you': 100}
复制代码

5.方法主要的方法啊,不是很多,我们需要单独得到其key以及其value;
  1. >>> d
  2. {'we': 1, 'will': 2, 'rock': 3, 'you': 4, '!': 5, '?': 6}
复制代码
1. keys
  1. >>> d.keys()
  2. dict_keys(['we', 'will', 'rock', 'you', '!', '?'])
复制代码
其类型很像是列表啊,但是不是列表,也很像zip一样是可迭代对象
  1. >>> dk =d.keys()
  2. >>> type(dk)
  3. <class 'dict_keys'>
  4. >>> for i in dk :
  5.     print(i)
  6.    
  7. we
  8. will
  9. rock
  10. you
  11. !
  12. ?
复制代码
2.value
  1. >>> d.values()
  2. dict_values([1, 2, 3, 4, 5, 6])
复制代码
返回值也是迭代对象
  1. >>> dv= d.values()
  2. >>> type(dv)
  3. <class 'dict_values'>
  4. >>>  for i in dv :
  5.     print(i)
  6.    
  7. 1
  8. 2
  9. 3
  10. 4
  11. 5
  12. 6
复制代码
3.items当然还有像是反用dict(zip())一样得到一个键值对的;
  1. >>> di = d.items()
  2. >>> di
  3. dict_items([('we', 1), ('will', 2), ('rock', 3), ('you', 4), ('!', 5), ('?', 6)])
复制代码
这个就很像是zip咯!!
  1. >>> type(di)
  2. <class 'dict_items'>
  3. >>> for i in di:
  4.     print(i)
  5.    
  6. ('we', 1)
  7. ('will', 2)
  8. ('rock', 3)
  9. ('you', 4)
  10. ('!', 5)
  11. ('?', 6)
  12. >>>
复制代码

4.clear
当然还有清空这中操作( 没错!!列表也有这个方法!);
  1. >>> c
  2. {'abandon': 1, 'adam': 2, 'alex': 3, 'ape': 4}
  3. >>> c.clear()
  4. >>>
  5. >>> c
  6. {}
复制代码
其实没学这个之前,比如一个列表,我们要清空都是直接将list=[]这样的赋值方式换一个指向罢了。但是这个方法对于字典来说,存在数据的危险,毕竟在内存中,虽然指向没有了,但是数据可能是存在的,于是为了数据的安全还是开发了clear的方法,而列表也是有的
插一嘴,lsit强制转换字典以及上述的可迭代对象会发生什么呢?
  1. >>> cc = list(a)
  2. >>> cc
  3. ['a', 'b', 'c', 'd']
  4. >>> cc.clear()
  5. >>> cc
  6. []
复制代码
  1. >>> dil = list(di)
  2. >>> dil
  3. [('we', 1), ('will', 2), ('rock', 3), ('you', 4), ('!', 5), ('?', 6)]
  4. >>> dkl = list(dk)
  5. >>> dkl
  6. ['we', 'will', 'rock', 'you', '!', '?']
复制代码
5.copy
当然离不开复制方法拉,这是浅复制的,id是会变的——真假美猴王!
  1. >>> id(a)
  2. 1932523629888
复制代码
6.pop和popitem
|  pop(...)
|      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
|      If key is not found, d is returned if given, otherwise KeyError is raised
|  
|  popitem(self, /)
|      Remove and return a (key, value) pair as a 2-tuple.
|      
|      Pairs are returned in LIFO (last-in, first-out) order.
|      Raises KeyError if the dict is empty.
pop的这个用法很像是get啊
  1. >>> a.pop('c','no!!')
  2. 'no!!'
  3. >>> a.pop('c')
  4. Traceback (most recent call last):
  5.   File "<pyshell>", line 1, in <module>
  6. KeyError: 'c'
复制代码
然后这个
返回值
返回一个键值对(key,value)形式,按照 LIFO(Last In First Out 后进先出法) 顺序规则,即最末尾的键值对。

实例
以下实例展示了 popitem() 方法的使用方法:

实例
#!/usr/bin/python3

site= {'name': '菜鸟教程', 'alexa': 10000, 'url': 'www.runoob.com'}
pop_obj=site.popitem()
print(pop_obj)  
print(site)
输出结果为:

('url', 'www.runoob.com')
{'name': '菜鸟教程', 'alexa': 10000}










想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-16 20:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表