字典

字典

标签(空格分隔): python-数据结构



概念

  • key-value 键值对的数据的集合
  • 可变的、无序的、key不重复

基本用法

  • 定义
    • d = dict() 或者 d = {}
    • dict(**kwargs) 使用 name=value 初始化一个字典
    • dict(iterable, **kwargs) 使用可迭代对象和 name=value构造字典, 不过可迭代对象的元素必须是二元结构
    • dict((('a', 1), ("b", 2)))
    • dict(mapping, **kwarg) 使用一个字典构键另一个字典
    • 类方法 dict.fromkeys(iterable, value)
      • d = dict.fromkeys(range(5))
      • d = dict.fromkeys(range(5), 0)
      • d = dict.fromkeys(range(5), [10]) # 小心使用,这里是同一个内存地址

字典元素的访问

  • d[key]
    • 返回 key 对应的 value
    • key 不存在,则抛出 KeyError 异常
  • get(key [, default])
    • 返回 key 对于的 value
    • key 不存在,则取 default, 如果没有设置缺省为 None
  • setdefault(key [, default])
    • 返回 key 对于的 value
    • key 不存在,添加 kv 对,valuedefault, 并返回default, 如果 default 没有设置,缺省为 None

字典元素的增加和修改

  • d[key] = value
    • key 对应的值 修改为 value
    • key 不存在,则抛出 KeyError 异常
  • update([other]) --> None
    • 使用另一个字典的 kv 对更新本字典
    • key 不存在, 则添加
    • key 存在,覆盖已经存在的 key 对应的值
    • 就地修改

字典元素的删除

  • pop(key [, default])

    • key 存在,移除它;并返回它的value
    • key 不存在,返回给定的 default
    • 如果没有给定 default, 且 key不存在则抛出KeyError异常
  • popitem()

    • 移除并返回一个任意的键值对
    • 字典为 empty, 抛出 KeyError 异常
  • clear()

    • 清空字典

字典删除

a = True
b = [6]
d = {'a': 1, 'b': b, 'c': [1,3,5]}
del a
del d['c']  # 这里看起来删除的是 [1, 3, 5] 实际是删除的c 和列表之间的关系,引用计数减一
del b[0] 
c =b
del c
del b 
b = d['b']

del a['c'] 看着像是删除了一个对象,本质上是减少了一个对象的引用,del 实际上删除的是名称,而不是对象;

本质删除的是,引用计数,真正的删除是交给垃圾回收机制做处理的


字典的遍历

# 遍历字典
for k, v in dict.items():
    # 遍历 item ,即 kv对--> ( k, v是解构)
    pass

# 遍历 key
# for k in dict:    #等价写法
for k in dict.keys():
    pass
 
# 遍历 value
for v in dict.values():
    pass
 
  • 总结

    • python3 中, keysvaluesitems 方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存中;
    • python2 中, 上述方法会返回一个新的列表,占据新的内存空间,所以python2 建议使用,iterkeysitervaluesiteritems 版本,返回一个迭代器,而不是一个 copy
  • 字典遍历和移除

  • 字典再迭代的过程中,不允许对字典进行增加元素,删除元素的操作,否则会引发 RuntimeError 异常

## 错误用法
d = dict.fromkeys(range(5), [10])
for i in d.keys():
    print(i)
    d.pop(i)
    
... Traceback (most recent call last):
...  File "<input>", line 1, in <module>
... RuntimeError: dictionary changed size during iteration
## 正确操作
d = dict.fromkeys(range(5), [10])
for i in list(d.keys()):
    print(i)
    d.pop(i)

缺省字典

  • collectionsl .defaultdict([defaultdict])
  • 第一个参数为 default_factory , 缺省是 None, 它提供一个初始化函数,当 key 不存在的 时候,会调用这个工厂函数 来生成 key 对应的 value
import random
from collections import defaultdict

d = defaultdict(list) # 参数为工厂函数

for c in "ABCDEFG":
    for i in range(random.randint(1, 5)):
        # 此处等价于 defaultdict(list); 当 defaultdict 识别到元素不存在,则添加缺省值
        # if c not in d:
        #     d[c] = []
        
        d[c].append(i)


有序字典

  • collectionsl.OrderedDict([items])

    • key 并不是按照加入的顺序排列的,可以使用 OrderedDict 记录顺序
    • 有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印
    • 3.6 版本的 Python 的字典就是记录 Key 插入的顺序(Ipython 不一定有效果)
  • 应用场景

    • 假如使用字典记录了 N 个产品,这些产品使用的ID 由小到大加入到字典中
    • 除了使用字典检索的遍历,有时候需要取出ID,但是希望是按照输入的顺序,因为输入顺序是有序的
    • 否则还需要重新把遍历到的值排序

练习题

1、用户输入一个数字,打印每一个数字及其重复次数

```
user_input = input(">> ").strip()

output = {}
if user_input.isdigit():
	for i in user_input:
		output[i] = output.get(i, 0) + 1
else:
	print("error - 用户输入的不是一个数字: {}".format(user_input))

# 扩展: 按照value值,降序打印
for i in sorted(output.items(), key=lambda x: x[1], reverse=True):  
	print(i)
```
原文地址:https://www.cnblogs.com/jingru-QAQ/p/11412242.html