看啥推荐读物
专栏名称: dwzb
目录
相关文章推荐
今天看啥  ›  专栏  ›  dwzb

玩转python字典与列表(中)

dwzb  · 掘金  ·  · 2018-05-28 03:23

玩转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编程

专栏目录:目录

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




原文地址:访问原文地址
快照地址: 访问文章快照