玩转python字典与列表(中)

本文首发于知乎

本文包括如下几个部分

  • 字典键值互换
  • 统计频数
  • 从字典中提取信息
  • 键值转换

字典键值互换

值唯一的情况

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
复制代码

这里说明一下,getsetdefault的区别是,当键不存在时,get会返回设置的默认值,而setdefault会将设置好的默认值对应到键上,更改原字典,之后再返回键的值。所以说get不能像setdefault那么用的原因是,初始化时不会自动修改原字典,需要通过赋值实现修改。而如果要找的键原本就在字典中存在的话,getsetdefault调用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)
复制代码

欢迎关注我的知乎专栏

专栏主页:python编程

专栏目录:目录

版本说明:软件及包版本说明

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值