今天看啥  ›  专栏  ›  简子逍

数据结构 | 字典 (下)

简子逍  · 简书  ·  · 2019-07-19 23:37

字典推导式

  • 合并大小写key的值。
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z':3}
mcase_frequency = {
    k.lower() :mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
    if k.lower() in ['a', 'b']
}
print(mcase_frequency)  # {'a': 17, 'b': 34}
  • 更换字典中keyvalue的值。
mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
print(mcase_frequency)  # {10: 'a', 34: 'b'}
  • 从字典中提取子集。
prices = {'ASP.NET':49.9, 'Python':69.9, 'Java':59.9, 'C':45.9, 'PHP':79.9}
p = {key:value for key,value in prices.items() if value > 50}
print(p)  # {'Python': 69.9, 'Java': 59.9, 'PHP': 79.9}

根据记录进行分组

  • 将字典或对象实例中的信息根据某个特定的字段,分组迭代数据。在itertools模块中提供了内置函数groupby(),能够方便地对数据进行分组处理。
from itertools import groupby
from operator import itemgetter

things = [('2012-05-21', 11), ('2012-05-21', 3), ('2012-05-22', 10),
          ('2012-05-22', 4), ('2012-05-22', 22), ('2012-05-23', 33)]
for key, items in groupby(things, itemgetter(0)):
    print(key, items)

# 输出
2012-05-21 <itertools._grouper object at 0x0000024AF884BDA0>
2012-05-22 <itertools._grouper object at 0x0000024AF884BDD8>
2012-05-23 <itertools._grouper object at 0x0000024AF884BD68>
from itertools import groupby
from operator import itemgetter

things = [('2012-05-21', 1), ('2012-05-21', 3), ('2012-05-22', 2),
          ('2012-05-22', 2), ('2012-05-22', 4), ('2012-05-23', 4)]

things.sort(key=itemgetter(1))
for data, items in groupby(things, key=itemgetter(1)):
    print(data)
    for i in items:
        print(' ', i)

# 输出
1
  ('2012-05-21', 1)
2
  ('2012-05-22', 2)
  ('2012-05-22', 2)
3
  ('2012-05-21', 3)
4
  ('2012-05-22', 4)
  ('2012-05-23', 4)

注意:groupby()只能检查连续的项,因此需要先进行sort()排序

  • 使用函数defaultdict()构建一个一键多值字典,进行分组。
from collections import defaultdict

things = [('2012-05-21', 1), ('2012-05-21', 3), ('2012-05-22', 2),
          ('2012-05-22', 4), ('2012-05-22', 2), ('2012-05-23', 4)]

rows = defaultdict(list)
for row in things:
    rows[row[1]].append(row)

for i, data in rows.items():
    print(i)
    for j in data:
        print(' ', j)

# 输出
1
  ('2012-05-21', 1)
2
  ('2012-05-22', 2)
  ('2012-05-22', 2)
3
  ('2012-05-21', 3)
4
  ('2012-05-22', 4)
  ('2012-05-23', 4)

函数defaultdict()一键多值的使用:

from collections import defaultdict

d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['a'].append(3)
print(d)  # defaultdict(<class 'list'>, {'a': [1, 2, 3]})

d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['a'].add(3)
print(d)  # defaultdict(<class 'set'>, {'a': {1, 2, 3}})

d = {}
d.setdefault('a', []).append(1)
d.setdefault('a', []).append(2)
d.setdefault('b', []).append(3)
print(d)  # {'a': [1, 2], 'b': [3]}

转换、换算数据

  • 函数sum()
>> sum([0, 1, 2])
3
>> sum((2, 3, 4), 1) 
10
>> sum([0, 1, 2, 3, 4], 2) 
12
  • 函数min()
>> min(0, 1, 2)
0
>> min([0, 1, 2]) 
0
  • 函数max()
>> max([0, 1, 2])
2
>> max(0, 1, 2) 
2

合并多个映射

collections模块中的ChainMap可以接收多个映射,在逻辑上可以表现为一个单独的映射结构,但是这些映射在字面上并不会合并在一起。
本质上只是简单地维护一个记录底层映射关系的列表,然后重定义常见的字典操作来扫描这个列表。如果有重复的键,则采用第一个映射中对应的值。

from collections import ChainMap

a = {'x' : 1, 'z' : 3}
b = {'y' : 2, 'z' : 4}
c = ChainMap(a, b)

print(c['x'])  # 1
print(c['y'])  # 2
print(c['z'])  # 3

print(len(c))  # 3
print(list(c.keys()))  # ['x', 'y', 'z']
print(list(c.values()))  # [1, 2, 3]

c['z'] = 10
c['w'] = 40
del c['x']
print(a)  # {'w': 40, 'z': 10}
print(b)  # {'y': 2, 'z': 4}

扫一扫关注微信公众号【四元群】,后台回复「代码」,获取完整代码资源。




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