Python字典类型常用操作大全!超全!

490 阅读6分钟
  • collect_dictionary

    反转具有非唯一可哈希值的字典。
    • 创建一个 collections.defaultdict 列表作为每个键的默认值。
    • dictionary.items() 与循环结合使用,使用 dict.append() 将字典的值映射到键。
    • 使用 dict()collections.defaultdict 转换为常规字典。
from collections import defaultdict

def collect_dictionary(obj):
  inv_obj = defaultdict(list)
  for key, value in obj.items():
    inv_obj[value].append(key)
  return dict(inv_obj)

defaultdict( factory_function)factory_function可以是listsetstr等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[]str对应的是空字符串,set对应set()int对应0

ages = {
  'Peter': 10,
  'Isabel': 10,
  'Anna': 9,
}
collect_dictionary(ages) # { 10: ['Peter', 'Isabel'], 9: ['Anna'] }
  • combine_values

    组合两个或多个字典,为每个键创建一个值列表。
    • 创建一个新的 collections.defaultdict,其中 list 作为每个键的默认值并循环遍历 dicts
    • 使用 dict.append() 将字典的值映射到键。
    • 使用 dict()collections.defaultdict 转换为常规字典。
from collections import defaultdict

def combine_values(*dicts):
  res = defaultdict(list)
  for d in dicts:
    for key in d:
      res[key].append(d[key])
  return dict(res)
d1 = {'a': 1, 'b': 'foo', 'c': 400}
d2 = {'a': 3, 'b': 200, 'd': 400}

combine_values(d1, d2) # {'a': [1, 3], 'b': ['foo', 200], 'c': [400], 'd': [400]}
  • group_by

    根据给定的函数对列表的元素进行分组。
    • 使用 collections.defaultdict 初始化字典。
    • fnfor 循环和 dict.append() 结合使用来填充字典。
    • 使用 dict() 将其转换为常规字典。
from collections import defaultdict

def group_by(lst, fn):
  d = defaultdict(list)
  for el in lst:
    d[fn(el)].append(el)
  return dict(d)
from math import floor

group_by([6.1, 4.2, 6.3], floor) # {4: [4.2], 6: [6.1, 6.3]}
group_by(['one', 'two', 'three'], len) # {3: ['one', 'two'], 5: ['three']}
  • sort_dict_by_value

    按值对给定字典进行排序。
    • 使用 dict.items()d 获取元组对列表,并使用 lambda 函数和 sorted() 对其进行排序。
    • 使用 dict() 将排序列表转换回字典。
    • 使用 sorted() 中的 reverse 参数根据第二个参数以相反的顺序对字典进行排序。
    • ⚠️ 注意:字典值必须是同一类型。
def sort_dict_by_value(d, reverse = False):
  return dict(sorted(d.items(), key = lambda x: x[1], reverse = reverse))
d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4}
sort_dict_by_value(d) # {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
sort_dict_by_value(d, True)
# {'five': 5, 'four': 4, 'three': 3, 'two': 2, 'one': 1}
  • sort_dict_by_key

    按键对给定的字典进行排序。
    • 使用 dict.items()d 中获取元组对列表,并使用 sorted() 对其进行排序。
    • 使用 dict() 将排序列表转换回字典。
    • 使用 sorted() 中的 reverse 参数根据第二个参数以相反的顺序对字典进行排序。
def sort_dict_by_key(d, reverse = False):
  return dict(sorted(d.items(), reverse = reverse))
d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4}
sort_dict_by_key(d) # {'five': 5, 'four': 4, 'one': 1, 'three': 3, 'two': 2}
sort_dict_by_key(d, True) # {'two': 2, 'three': 3, 'one': 1, 'four': 4, 'five': 5}
  • map_dictionary

    使用函数将列表的值映射到字典,其中键值对由作为键的原始值和作为值的函数的结果组成。

    • 使用 map()fn 应用于列表的每个值。
    • 使用 zip() 将原始值与 fn 生成的值配对。
    • 使用 dict() 返回适当的字典。
def map_dictionary(itr, fn):
  return dict(zip(itr, map(fn, itr)))
map_dictionary([1, 2, 3], lambda x: x * x) # { 1: 1, 2: 4, 3: 9 }
  • map_values

    创建一个字典,其键与提供的字典的键相同,值为提供的字典的值运行提供的函数所生成。
    • 使用 dict.items() 遍历字典,将 fn 生成的值分配给新字典的每个键。
def map_values(obj, fn):
  return dict((k, fn(v)) for k, v in obj.items())
users = {
  'fred': { 'user': 'fred', 'age': 40 },
  'pebbles': { 'user': 'pebbles', 'age': 1 }
}
map_values(users, lambda u : u['age']) # {'fred': 40, 'pebbles': 1}
  • get

    从字典或列表中检索给定选择器列表指示的嵌套键的值。

    • 使用 functools.reduce() 遍历选择器列表。
    • 为选择器中的每个键应用 operator.getitem(),检索要用作下一次迭代的迭代对象的值。
from functools import reduce 
from operator import getitem

def get(d, selectors):
  return reduce(getitem, selectors, d)
users = {
  'freddy': {
    'name': {
      'first': 'fred',
      'last': 'smith' 
    },
    'postIds': [1, 2, 3]
  }
}
get(users, ['freddy', 'name', 'last']) # 'smith'
get(users, ['freddy', 'postIds', 1]) # 2
  • invert_dictionary

    反转具有唯一可哈希值的字典。
    • dictionary.items() 与列表推导结合使用来创建一个值和键倒置的新字典。
def invert_dictionary(obj):
  return { value: key for key, value in obj.items() }
ages = {
  'Peter': 10,
  'Isabel': 11,
  'Anna': 9,
}
invert_dictionary(ages) # { 10: 'Peter', 11: 'Isabel', 9: 'Anna' }
  • merge_dictionaries

    合并两个或多个字典。

    • 创建一个新的字典并循环遍历字典,使用 dictionary.update() 将每个键值对添加到结果中。
def merge_dictionaries(*dicts):
  res = dict()
  for d in dicts:
    res.update(d)
  return res
ages_one = {
  'Peter': 10,
  'Isabel': 11,
}
ages_two = {
  'Anna': 9
}
merge_dictionaries(ages_one, ages_two)
# { 'Peter': 10, 'Isabel': 11, 'Anna': 9 }
  • pluck

    将字典列表转换为与指定键对应的值列表。
    • 使用列表推导和 dict.get() 来获取 lst 中每个字典的键值。
def pluck(lst, key):
  return [x.get(key) for x in lst]
simpsons = [  { 'name': 'lisa', 'age': 8 },  { 'name': 'homer', 'age': 36 },  { 'name': 'marge', 'age': 34 },  { 'name': 'bart', 'age': 10 }]
pluck(simpsons, 'age') # [8, 36, 34, 10]
  • find_keys

    在提供的字典中查找具有给定值的所有键。
    • 使用 dictionary.items()、生成器和 list() 返回值等于 val 的所有键。
def find_keys(dict, val):
  return list(key for key, value in dict.items() if value == val)
ages = {
  'Peter': 10,
  'Isabel': 11,
  'Anna': 10,
}
find_keys(ages, 10) # [ 'Peter', 'Anna' ]
  • find_keys

    在提供的字典中查找具有给定值的第一个键。
    • 使用 dictionary.items()next() 返回值等于 val 的第一个键。
def find_key(dict, val):
  return next(key for key, value in dict.items() if value == val)
ages = {
  'Peter': 10,
  'Isabel': 11,
  'Anna': 9,
}
find_key(ages, 11) # 'Isabel'
  • to_dictionary

    将两个列表组合成一个字典,其中第一个列表的元素用作键,第二个列表的元素用作值。第一个列表的值必须是唯一且可散列的。
    • 结合使用 zip()dict() 将两个列表的值组合到一个字典中。
def to_dictionary(keys, values):
  return dict(zip(keys, values))
to_dictionary(['a', 'b'], [1, 2]) # { a: 1, b: 2 }
  • dict_to_list

    将字典转换为元组列表。
    • 使用 dict.items()list() 从给定字典中获取元组列表。
def dict_to_list(d):
  return list(d.items())
d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4}
dict_to_list(d) # [('one', 1), ('three', 3), ('five', 5), ('two', 2), ('four', 4)]
  • keys_only

    创建平面字典中所有键的平面列表。
    • 使用 dict.keys() 返回给定字典中的键。
    • 返回上一个结果的 list()
def keys_only(flat_dict):
  return list(flat_dict.keys())
ages = {
  'Peter': 10,
  'Isabel': 11,
  'Anna': 9,
}
keys_only(ages) # ['Peter', 'Isabel', 'Anna']
  • values_only

    返回平面字典中所有值的平面列表。
    • 使用 dict.values() 返回给定字典中的值。
    • 返回上一个结果的 list()
def values_only(flat_dict):
  return list(flat_dict.values())
ages = {
  'Peter': 10,
  'Isabel': 11,
  'Anna': 9,
}
values_only(ages) # [10, 11, 9]
  • key_of_max

    在字典中查找最大值的键。
    • 使用 max() 并将 key 参数设置为 dict.get() 以查找并返回给定字典中最大值的键。
def key_of_max(d):
  return max(d, key = d.get)
key_of_max({'a':4, 'b':0, 'c':13}) # c
  • key_of_min

    在字典中查找最小值的键。
    • 使用 min() 并将 key 参数设置为 dict.get() 以查找并返回给定字典中最小值的键。
def key_of_min(d):
  return min(d, key = d.get)
key_of_min({'a':4, 'b':0, 'c':13}) # b
  • key_in_dict

    检查给定键是否存在于字典中。 使用 in 运算符检查 d 是否包含键。
def key_in_dict(d, key):
  return (key in d)
d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4}
key_in_dict(d, 'three') # True

Tips

  • 尽量使用 dict.get(key) 而不是 dict[key]

Python 中的一个常见争论就是字典值的检索,这可以使用 dict[key]dict.get(key) 来完成。 尽管您可以使用其中任何一个来获得相同的结果,但通常首选 dict.get(),因为它接受第二个参数,如果给定字典中不存在该键,则该参数充当默认值。由于这个属性,dict.get() 将始终返回一个值,而 dict[key] 如果给定键丢失,则会引发 KeyError

a = { 'max': 200 }
b = { 'min': 100, 'max': 250 }
c = { 'min': 50 }

a['min'] + b['min'] + c['min'] # throws KeyError
a.get('min', 0) + b.get('min', 0) + c.get('min', 0) # 150