本文首发于知乎 https://zhuanlan.zhihu.com/p/37222908
本文包括如下几个部分
字典键值互换
统计频数
从字典中提取信息
键值转换
字典键值互换
值唯一的情况
- d = {'a': 1, 'b': 2}
- {v: k for k, v in d.items()}
- # {1: 'a', 2: 'b'}
值不唯一的情况
d = {'a': 1, 'b': 2, 'c': 3, 'd': 1}
- # 想要输出
- {1: ['a', 'd'], 2: ['b'], 3: ['c']}
- # 第一种方法
- result = {}
- for k, v in d.items():
- result[v] = result.get(v, [])
- result[v].append(k)
- result
- # 第二种方法
- result = {}
- for k, v in d.items():
- result[v] = result.get(v, []) + [k]
- result
- # 第三种方法
- result = {}
- for k, v in d.items():
- result.setdefault(v, []).append(k)
- result
这里说明一下, get 和 setdefault 的区别是, 当键不存在时, get 会返回设置的默认值, 而 setdefault 会将设置好的默认值对应到键上, 更改原字典, 之后再返回键的值. 所以说 get 不能像 setdefault 那么用的原因是, 初始化时不会自动修改原字典, 需要通过赋值实现修改. 而如果要找的键原本就在字典中存在的话, get 和 setdefault 调用 append 都能对原字典进行修改, 具体情况读者可以自己去试.
如果使用 collections 模块, 还有第四种方法
- from collections import defaultdict
- result = defaultdict(list)
- for k, v in d.items():
- result[v].append(k)
- dict(result)
后面多有用这个思路来完成的, 就只展示其中一种方法了.
统计频数
要统计一个列表中各个元素出现的次数, 最后用字典的形式呈现, 可以使用 collections 模块中的 defaultdict
- from collections import defaultdict
- m = ['a', 'b', 'a', 'b', 'a', 'c']
- d = defaultdict(lambda: 0)
- for k in m:
- d[k] += 1
- dict(d)
- # {'a': 3, 'b': 2, 'c': 1}
其实 collections 模块还提供了一个专门的计数器 Counter
- from collections import Counter
- m = ['a', 'b', 'a', 'b', 'a', 'c']
- c = Counter()
- for k in m:
- c[k] += 1
- dict(c)
- # {'a': 3, 'b': 2, 'c': 1}
从字典中提取信息
我们现在有这个字典
- m = {'Bob': {'age': 30, 'country': 'America'},
- 'Mary': {'age': 20, 'country': 'China'},
- 'Frank': {'age': 25, 'country': 'America'}}
1. 提取出
{'America': ['Frank', 'Bob'], 'China': ['Mary']}
代码:
- result = {}
- for k, v in m.items():
- result.setdefault(v['country'], []).append(k)
- result
2. 提取出
{'America': [25, 30], 'China': [20]}
代码
- result = {}
- for k, v in m.items():
- result.setdefault(v['country'], []).append(v['age'])
- result
键值转换
还是这个字典
- m = {'Bob': {'age': 30, 'country': 'America'},
- 'Mary': {'age': 20, 'country': 'China'},
- 'Frank': {'age': 25, 'country': 'America'}}
现在想要得到下面这种形式 (即将键移入字典变成一个值)
- [{'name': 'Bob', 'age': 30, 'country': 'America'},
- {'name': 'Mary', 'age': 20, 'country': 'China'},
- {'name': 'Frank', 'age': 25, 'country': 'America'}]
只需要
[{**{'name': name}, **infos} for name, infos in m.items()]
注: 使用双星号是合并两个字典的好方法, 注意和 将字典列表合并为一个字典相区分
反过来的过程:
- m = [{'name': 'Bob', 'age': 30, 'country': 'America'},
- {'name': 'Mary', 'age': 20, 'country': 'China'},
- {'name': 'Frank', 'age': 25, 'country': 'America'}]
- from collections import defaultdict
- result = defaultdict(dict)
- for d in m:
- for k, v in d.items():
- if k != 'name':
- result[d['name']].update({k: v})
- dict(result)
来源: https://juejin.im/post/5b09511ef265da0de574175b