文章目录
这里是一段防爬虫文本,请读者忽略。
本文原创首发于CSDN,作者IDYS
博客首页:https://blog.csdn.net/weixin_41633902/
本文链接:https://blog.csdn.net/weixin_41633902/article/details/107500135
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
写在开头的话
- 请记住:实践是掌握知识的最快方法
- 如果你只是怀着看看的态度去快速浏览文章,而不去认认真真的把文章里面讲的任何一个知识点去实践一遍,那么你永远也掌握不了它
- 生命不息,折腾不止!
Python之字典
00. 概述
key-value
键值对的数据的集合- 可变的、无序的、
key
不重复
字典dict定义、 初始化
d = dict()
或者d = {}
dict(**kwargs)
使用name=value
对初始化一个字典dict(iterable, **kwarg)
使用可迭代对象和name=value
对构造字典,不过可迭代对象的元素必须是 一个二元结构d = dict(((1,'a'),(2,'b')))
或者d = dict(([1,'a'],[2,'b']))
dict(mapping, **kwarg)
使用一个字典构建另一个字典d = {'a':10, 'b':20, 'c':None, 'd':[1,2,3]}
- 类方法
dict.fromkeys(iterable, value)
d = dict.fromkeys(range(5))
d = dict.fromkeys(range(5),0)
定义字典的时候,要求
key
是可以hash
的类型
- 演示
dict1 = {}
print(type(dict1))
dict2 = dict()
print(dict2)
dict3 = dict(name='idys', age=18, tall=182)
print(dict3)
dict4 = dict(enumerate(range(10), start=2))
q = enumerate(range(10), start=2)
for i, num in q:
print("{:^3d}:{:^3d}".format(i, num))
print()
print(dict4)
dict5 = dict(((1, "a"), ))
print(dict5)
dict6 = dict((('name', "idys"), ("age", 20)))
print(dict6)
dict7 = dict((['hexo', 'blog'], ))
print(dict7)
dict8 = dict((['what', "can"], ["name", 10]))
print(dict8)
dict9 = {"12": "who", 'age':19, "list":[1, 2, 3, '2']}
print(dict9)
dict10 = dict.fromkeys(range(10))
print(dict10)
dict11 = dict.fromkeys(range(5), [1, 2])
print(dict11)
dict11[4].append(3)
print(dict11)
- 运行结果
<class 'dict'>
{}
{'name': 'idys', 'age': 18, 'tall': 182}
2 : 0
3 : 1
4 : 2
5 : 3
6 : 4
7 : 5
8 : 6
9 : 7
10 : 8
11 : 9
{2: 0, 3: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9}
{1: 'a'}
{'name': 'idys', 'age': 20}
{'hexo': 'blog'}
{'what': 'can', 'name': 10}
{'12': 'who', 'age': 19, 'list': [1, 2, 3, '2']}
{0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None}
{0: [1, 2], 1: [1, 2], 2: [1, 2], 3: [1, 2], 4: [1, 2]}
{0: [1, 2, 3], 1: [1, 2, 3], 2: [1, 2, 3], 3: [1, 2, 3], 4: [1, 2, 3]}
01. 字典元素的访问
d[key]
- 返回
key
对应的值value
key
不存在抛出KeyError
异常
- 返回
get(key[, default])
- 返回
key
对应的值value
key
不存在返回缺省值,如果没有设置缺省值就返回None
- 返回
setdefault(key[, default])
- 返回
key
对应的值value
key
不存在,添加kv
对,value
为default
,并返回default
,如果default
没有设置,缺省为None
- 返回
- 演示
dict1 = dict(name='idys', age=18)
print(dict1)
print(dict1.get("name", 'none')) # 如果有name
# 这个key,那么返回name这个key对应的value,如果没
# 有name这个key,就返回自己设置的字符串'none'
print(dict1.setdefault('age', 20))
print(dict1)
print(dict1.setdefault('date', 1990))
print(dict1)
print(dict1.setdefault('date'))
print(dict1)
print(dict1.setdefault('who'))
print(dict1)
- 运行结果
{'name': 'idys', 'age': 18}
idys
18
{'name': 'idys', 'age': 18}
1990
{'name': 'idys', 'age': 18, 'date': 1990}
1990
{'name': 'idys', 'age': 18, 'date': 1990}
None
{'name': 'idys', 'age': 18, 'date': 1990, 'who': None}
02. 字典增加和修改
d[key] = value
- 将
key
对应的值修改为value
key
不存在添加新的kv
对
- 将
update([other]) -> None
- 使用另一个字典的
kv
对更新本字典 key
不存在,就添加key
存在,覆盖已经存在的key
对应的值- 就地修改
d.update(red=1)
d.update((('red',2),))
d.update({'red':3})
- 使用另一个字典的
- 演示
dict1 = dict((("hexo", "blog"), ('description', 'great')))
print(dict1)
dict1['color'] = 'gloden'
print(dict1)
dict1.update(is_global=True)
print(dict1)
dict1.update((['id_else', True],))
print(dict1)
dict1.update((("num", 23), ('num1', 24)))
print(dict1)
dict2 = {5:1000, 6:'who'}
print(dict1.update(dict2, red=70))
print(dict1)
- 运行结果
{'hexo': 'blog', 'description': 'great'}
{'hexo': 'blog', 'description': 'great', 'color': 'gloden'}
{'hexo': 'blog', 'description': 'great', 'color': 'gloden', 'is_global': True}
{'hexo': 'blog', 'description': 'great', 'color': 'gloden', 'is_global': True, 'id_else': True}
{'hexo': 'blog', 'description': 'great', 'color': 'gloden', 'is_global': True, 'id_else': True, 'num': 23, 'num1': 24}
None
{'hexo': 'blog', 'description': 'great', 'color': 'gloden', 'is_global': True, 'id_else': True, 'num': 23, 'num1': 24, 5: 1000, 6: 'who', 'red': 70}
03. 字典删除
pop(key[, default])
key
存在,移除它,并返回它的value
key
不存在,返回给定的default
default
未设置,key
不存在则抛出KeyError
异常
popitem()
- 移除并返回一个任意的键值对
- 字典为
empty
,抛出KeyError
异常 clear()
- 清空字典
- 演示
dict1 = dict({(123, 'am'), ('name', 'who'), ('who', 90), ('age', 80)})
print(dict1)
print(dict1.pop(123))
print(dict1)
print(dict1.pop("qwe",'nonevalue'))
print(dict1)
dict1.popitem()
print(dict1)
- 运行结果
{'age': 80, 123: 'am', 'name': 'who', 'who': 90}
am
{'age': 80, 'name': 'who', 'who': 90}
nonevalue
{'age': 80, 'name': 'who', 'who': 90}
{'age': 80, 'name': 'who'}
del
语句del
看着像删除了一个对象,本质上减少了一个对象的引用,del
实际上删除的是名称,而不是对象
04. 字典遍历和移除
-
for ... in dict
-
遍历key
for k in d:
print(k)
for k in d.keys():
print(k)
for ... in dict
- 遍历
value
- 遍历
for k in d:
print(d[k])
for k in d.keys():
print(d.get(k))
for v in d.values():
print(v)
- 演示
dict1 = {'a': 16, 'b': 8, "list": [12, 56, 78]}
# 遍历keys
for i in dict1:
print(i)
print()
for i in dict1.keys():
print(i)
# 遍历value
print()
for i in dict1:
print(dict1[i])
print()
for i in dict1:
print(dict1.get(i))
print()
for i in dict1.values():
print(i)
print()
for i in dict1.keys():
print(dict1[i])
- 运行结果
a
b
list
a
b
list
16
8
[12, 56, 78]
16
8
[12, 56, 78]
16
8
[12, 56, 78]
16
8
[12, 56, 78]
for ... in dict
- 遍历
item
,即kv
对
for item in d.items():
print(item)
for item in d.items():
print(item[0], item[1])
for k,v in d.items():
print(k, v)
for k, _ in d.items():
print(k)
for _ ,v in d.items():
print(v)
- 总结
Python3
中,keys
、values
、items
方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存中Dictionary view
对象- 字典的
entry
的动态的视图,字典变化,视图将反映出这些变化
Python2
中,上面的方法会返回一个新的列表,占据新的内存空间。所以Python2
建议使用iterkeys
、itervalues
、iteritems
版本,返回一个迭代器,而不是一个copy
- 如何在遍历的时候移除元素
d = dict(a=1, b=2, c='abc')
keys = []
for k,v in d.items():
if isinstance(v, object):
keys.append(k)
for k in keys:
d.pop(k)
else:
print(len(d))
05. 字典的key
key
的要求和set
的元素要求一致set
的元素可以就是看做key
,set
可以看做dict
的简化版hashable
可哈希才可以作为key
,可以使用hash()
测试d = {1 : 0, 2.0 : 3, "abc" : None, ('hello', 'world', 'python') : "string", b'abc' : '135
- 凡是可变的都不能作为
key
06. defaultdict
collections.defaultdict([default_factory[, ...]])
- 第一个参数是
default_factory
,缺省是None
,它提供一个初始化函数。当key
不存在的时候,会调用这个工厂函数来生成key
对应的value
- 第一个参数是
- 演示
import random
from collections import defaultdict
d1 = {}
d2 = defaultdict(list)
for k in 'abcdefg':
for i in range(random.randint(1, 3)):
if k not in d1.keys():
d1[k] = []
d1[k].append(i)
print(d1)
for k in 'objectwho':
for i in range(random.randint(1, 4)):
d2[k].append(i)
print(d2)
d3 = defaultdict(int)
for k in "who are who i i love":
d3[k] += 1
print(d3)
print(sorted(d3.items()))
- 运行结果
{'a': [0, 1, 2], 'b': [0, 1], 'c': [0, 1, 2], 'd': [0, 1], 'e': [0], 'f': [0, 1, 2], 'g': [0, 1, 2]}
defaultdict(<class 'list'>, {'o': [0, 1, 2, 0, 1, 2], 'b': [0, 1, 2], 'j': [0, 1, 2], 'e': [0, 1, 2, 3], 'c': [0, 1, 2], 't': [0], 'w': [0, 1], 'h': [0, 1, 2, 3]})
defaultdict(<class 'int'>, {'w': 2, 'h': 2, 'o': 3, ' ': 5, 'a': 1, 'r': 1, 'e': 2, 'i': 2, 'l': 1, 'v': 1})
[(' ', 5), ('a', 1), ('e', 2), ('h', 2), ('i', 2), ('l', 1), ('o', 3), ('r', 1), ('v', 1), ('w', 2)]
07. OrderedDict
collections.OrderedDict([items])
key
并不是按照加入的顺序排列,可以使用OrderedDict
记录顺序- 有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印
3.6
版本的Python的字典就是记录key
插入的顺序(IPython不一定有效果)- 应用场景:
- 假如使用字典记录了
N
个产品,这些产品使用ID
由小到大加入到字典中 - 除了使用字典检索的遍历,有时候需要取出ID,但是希望是按照输入的顺序,因为输入顺序是有序的
- 否则还需要重新把遍历到的值排序
- 假如使用字典记录了
08. 字典练习
8.1数字重复统计
- 随机产生
100
个整数 - 数字的范围
[-1000, 1000]
- 升序输出所有不同的数字及其重复的次数
思路
-
利用
random
模块的randint()
产生-1000 ~ 1000
的数字 -
利用字典对产生的数字统计出现的次数,将
value
设为int
类型即可 -
利用
sorted
对字典排序
- 演示
import random
from collections import defaultdict
dict1 = defaultdict(int)
for i in range(100):
dict1[random.randint(-1000, 1000)] += 1
a = sorted(dict1.keys())
for i in a:
print(i, dict1[i]," ")
print(sorted(dict1.items(), key=lambda item:item[0]))
- 运行结果
-988 1
-987 1
-977 1
-971 1
-958 1
-949 1
-908 1
-886 1
-882 1
-878 1
-869 1
-833 2
-819 1
-808 1
-788 1
-787 1
-779 1
-755 1
-750 1
-741 1
-726 1
-721 1
-698 1
-697 1
-662 1
-611 1
-573 1
-548 1
-545 1
-537 1
-506 1
-504 1
-494 1
-440 1
-379 1
-366 1
-340 1
-308 1
-302 1
-277 1
-256 1
-215 1
-160 1
-120 1
-80 1
-74 1
-66 1
-57 1
-56 1
-48 1
-27 1
20 1
66 1
84 1
110 1
117 1
122 1
126 1
136 1
152 1
171 1
242 1
269 1
290 1
294 1
312 1
330 1
333 1
348 1
353 1
432 1
436 1
441 1
448 1
456 1
461 1
468 1
520 1
527 1
542 1
559 1
622 2
625 1
694 1
702 1
704 1
745 1
781 1
782 1
798 1
799 1
836 1
877 1
902 1
916 1
917 1
965 1
982 1
[(-988, 1), (-987, 1), (-977, 1), (-971, 1), (-958, 1), (-949, 1), (-908, 1), (-886, 1), (-882, 1), (-878, 1), (-869, 1), (-833, 2), (-819, 1), (-808, 1), (-788, 1), (-787, 1), (-779, 1), (-755, 1), (-750, 1), (-741, 1), (-726, 1), (-721, 1), (-698, 1), (-697, 1), (-662, 1), (-611, 1), (-573, 1), (-548, 1), (-545, 1), (-537, 1), (-506, 1), (-504, 1), (-494, 1), (-440, 1), (-379, 1), (-366, 1), (-340, 1), (-308, 1), (-302, 1), (-277, 1), (-256, 1), (-215, 1), (-160, 1), (-120, 1), (-80, 1), (-74, 1), (-66, 1), (-57, 1), (-56, 1), (-48, 1), (-27, 1), (20, 1), (66, 1), (84, 1), (110, 1), (117, 1), (122, 1), (126, 1), (136, 1), (152, 1), (171, 1), (242, 1), (269, 1), (290, 1), (294, 1), (312, 1), (330, 1), (333, 1), (348, 1), (353, 1), (432, 1), (436, 1), (441, 1), (448, 1), (456, 1), (461, 1), (468, 1), (520, 1), (527, 1), (542, 1), (559, 1), (622, 2), (625, 1), (694, 1), (702, 1), (704, 1), (745, 1), (781, 1), (782, 1), (798, 1), (799, 1), (836, 1), (877, 1), (902, 1), (916, 1), (917, 1), (965, 1), (982, 1)]
8.2 字符串重复统计
- 字符表
'abcdefghijklmnopqrstuvwxyz'
- 随机挑选
2
个字母组成字符串,共挑选100
个 - 降序输出所有不同的字符串及重复的次数
- 思路
- 利用
randint
函数随机生成指定范围的两个数字,然后去字符表查找下面对应的元素,然后组合 - 用字典对找到的数字进行统计
- 利用
sorted
排序
- 演示
import random
import collections
str1 = 'abcdefghijklmnopqrstuvwxyz'
dict1 = collections.defaultdict(int)
for i in range(100):
new_str = str1[random.randint(0, len(str1)-1)]+str1[random.randint(0, len(str1)-1)]
dict1[new_str] +=1
print(sorted(dict1.items(), key=lambda item:item[1], reverse=True))
- 运行结果
[('xm', 2), ('at', 2), ('ln', 2), ('mp', 2), ('ns', 2), ('mv', 1), ('pz', 1), ('ep', 1), ('lj', 1), ('ld', 1), ('wp', 1), ('eh', 1), ('wi', 1), ('rn', 1), ('el', 1), ('xi', 1), ('lb', 1), ('fl', 1), ('rj', 1), ('zy', 1), ('tt', 1), ('tg', 1), ('st', 1), ('cm', 1), ('ae', 1), ('un', 1), ('ib', 1), ('ek', 1), ('nm', 1), ('mw', 1), ('yu', 1), ('lf', 1), ('ti', 1), ('mm', 1), ('np', 1), ('of', 1), ('uw', 1), ('xq', 1), ('ee', 1), ('qs', 1), ('yq', 1), ('aw', 1), ('rb', 1), ('hz', 1), ('jr', 1), ('ly', 1), ('nl', 1), ('ub', 1), ('ev', 1), ('yy', 1), ('dd', 1), ('be', 1), ('ho', 1), ('fw', 1), ('du', 1), ('kf', 1), ('nx', 1), ('dl', 1), ('yj', 1), ('fv', 1), ('ea', 1), ('pi', 1), ('jv', 1), ('yd', 1), ('bv', 1), ('oe', 1), ('jl', 1), ('fk', 1), ('qw', 1), ('kc', 1), ('yv', 1), ('bd', 1), ('zv', 1), ('et', 1), ('ef', 1), ('ja', 1), ('pa', 1), ('qk', 1), ('nf', 1), ('tm', 1), ('jy', 1), ('ur', 1), ('rv', 1), ('nn', 1), ('qu', 1), ('yc', 1), ('sm', 1), ('lu', 1), ('xw', 1), ('vk', 1), ('ez', 1), ('rk', 1), ('cz', 1), ('tv', 1), ('ne', 1)]
写在最后的话:
- 无论每个知识点的难易程度如何,我都会尽力将它描绘得足够细致
- 欢迎关注我的CSDN博客,IDYS’BLOG
- 持续更新内容:
linux基础 | 数据通信(路由交换,WLAN) | Python基础 | 云计算 - 如果你有什么疑问,或者是难题。欢迎评论或者私信我。你若留言,我必回复!
- 虽然我现在还很渺小,但我会做好每一篇内容。谢谢关注!