MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python访问字典值的多种方式

2021-08-173.8k 阅读

通过键直接访问

在Python中,字典是一种无序的键值对集合。访问字典值最常见的方式就是通过键直接访问。字典的设计初衷就是为了能快速地根据键找到对应的值,就像现实生活中查字典,通过查找词条(键)来获取解释(值)。

基本语法

假设我们有一个字典 my_dict,通过方括号 [] 并在其中传入键来获取对应的值,语法如下:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
value = my_dict['name']
print(value)  

在上述代码中,我们定义了一个字典 my_dict,包含三个键值对。然后通过 my_dict['name'] 获取了键 'name' 对应的值 'Alice',并将其打印出来。

键不存在时的情况

如果使用上述方式访问一个不存在的键,Python会抛出 KeyError 异常。例如:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
try:
    value = my_dict['gender']
    print(value)
except KeyError:
    print('键不存在')  

在这段代码中,由于字典 my_dict 中不存在 'gender' 这个键,所以当执行 my_dict['gender'] 时会引发 KeyError 异常,程序会捕获这个异常并打印出 '键不存在'

这种异常机制在某些情况下可能会导致程序中断,尤其是在对键的存在性不确定时。为了避免这种情况,我们可以使用 get 方法。

使用get方法访问

get 方法是字典对象提供的一个非常实用的方法,用于获取字典中指定键的值。与直接通过键访问不同,get 方法在键不存在时不会抛出异常,而是返回一个默认值。

get方法的基本语法

get 方法的基本语法如下:

my_dict.get(key[, default])

其中,key 是要查找的键,default 是可选参数,当键不存在时返回该默认值,如果不提供 default 参数,默认返回 None

下面看一个示例:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
value1 = my_dict.get('name')
print(value1)  
value2 = my_dict.get('gender')
print(value2)  
value3 = my_dict.get('gender', '未指定')
print(value3)  

在上述代码中,通过 my_dict.get('name') 获取了 'name' 键对应的值 'Alice' 并打印。对于不存在的键 'gender',第一次使用 my_dict.get('gender') 时,由于没有提供默认值,所以返回 None 并打印。第二次使用 my_dict.get('gender', '未指定'),提供了默认值 '未指定',所以当键 'gender' 不存在时,返回并打印 '未指定'

get方法的优势

使用 get 方法的主要优势在于它可以优雅地处理键不存在的情况,避免程序因 KeyError 异常而中断。这在很多实际场景中非常有用,比如在处理用户输入数据构建字典,然后获取某些可能存在也可能不存在的键值时。

例如,假设我们从用户输入中获取一些信息并构建字典,然后尝试获取用户可能未提供的信息:

user_info = {}
name = input('请输入你的名字:')
if name:
    user_info['name'] = name
age_str = input('请输入你的年龄:')
if age_str:
    user_info['age'] = int(age_str)

age = user_info.get('age', 18)
print(f'你的年龄是:{age}')

在这个示例中,用户可能不输入年龄,此时字典 user_info 中就不存在 'age' 键。通过 get 方法获取 'age' 键的值,并在键不存在时返回默认值 18,这样程序可以正常运行,不会因为键不存在而报错。

通过遍历字典访问值

有时候,我们可能需要遍历字典中的所有值,而不仅仅是获取某个特定键的值。Python提供了多种方式来遍历字典的值。

使用values方法

字典对象的 values 方法返回一个可迭代对象,包含字典中所有的值。我们可以使用 for 循环来遍历这些值。

示例代码如下:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
for value in my_dict.values():
    print(value)  

在上述代码中,my_dict.values() 返回一个包含字典所有值的可迭代对象,通过 for 循环,依次将每个值赋值给 value 变量,并打印出来。

需要注意的是,values 方法返回的可迭代对象不是一个列表,而是一个类似列表的可迭代视图对象。如果需要将其转换为列表,可以使用 list() 函数,例如:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
value_list = list(my_dict.values())
print(value_list)  

这样就将字典的值转换为了一个列表并打印出来。

同时获取键和值 - 使用items方法

在很多情况下,我们不仅需要访问字典的值,还需要同时获取对应的键。这时可以使用字典的 items 方法。items 方法返回一个可迭代对象,其中的每个元素都是一个包含键和值的元组。

示例代码如下:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
for key, value in my_dict.items():
    print(f'键:{key},值:{value}')  

在上述代码中,通过 for 循环,my_dict.items() 返回的每个元组中的第一个元素被赋值给 key,第二个元素被赋值给 value,然后打印出键值对信息。

同样,items 方法返回的也是一个可迭代视图对象,如果需要转换为列表,可以使用 list() 函数:

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
item_list = list(my_dict.items())
print(item_list)  

这样就将字典的键值对转换为了一个包含元组的列表并打印出来。

使用defaultdict访问值

defaultdict 是Python标准库 collections 模块中的一个类,它是字典的一个子类,提供了一种更方便的方式来处理不存在的键。

defaultdict的基本使用

当使用 defaultdict 创建一个字典时,需要传入一个可调用对象(例如函数)作为参数。这个可调用对象会在访问不存在的键时被调用,返回一个默认值。

示例代码如下:

from collections import defaultdict


def default_value():
    return '默认值'


my_dict = defaultdict(default_value)
value1 = my_dict['name']
print(value1)  

在上述代码中,首先从 collections 模块导入 defaultdict。然后定义了一个函数 default_value,它返回 '默认值'。接着使用 defaultdict 创建了一个字典 my_dict,并将 default_value 函数作为参数传入。当访问不存在的键 'name' 时,defaultdict 会调用 default_value 函数来返回一个默认值 '默认值',并打印出来。

使用常见的可调用对象作为默认值生成器

除了自定义函数外,还可以使用一些常见的可调用对象作为 defaultdict 的默认值生成器。例如,使用 int 函数作为默认值生成器,可以创建一个默认值为 0 的字典,这在统计某些数据时非常有用。

示例代码如下:

from collections import defaultdict

my_dict = defaultdict(int)
my_dict['count'] += 1
print(my_dict['count'])  

在上述代码中,使用 defaultdict(int) 创建了一个字典 my_dict。当访问不存在的键 'count' 时,defaultdict 会调用 int() 函数,返回默认值 0。然后对 my_dict['count'] 进行加 1 操作,最后打印出 1

同样,也可以使用 list 函数作为默认值生成器来创建一个默认值为列表的字典,这在需要将多个值分组到一个键下时很有用。

示例代码如下:

from collections import defaultdict

my_dict = defaultdict(list)
my_dict['group1'].append('item1')
my_dict['group1'].append('item2')
print(my_dict['group1'])  

在这段代码中,使用 defaultdict(list) 创建了字典 my_dict。当访问不存在的键 'group1' 时,defaultdict 会调用 list() 函数,返回一个空列表。然后向这个列表中添加了两个元素 'item1''item2',最后打印出 ['item1', 'item2']

使用ChainMap访问多个字典的值

ChainMap 也是 collections 模块中的一个类,它可以将多个字典组合成一个单一的映射结构。通过 ChainMap,我们可以方便地访问多个字典中的值,就好像它们是一个字典一样。

ChainMap的基本使用

假设我们有两个字典,并且想以一种统一的方式访问它们的值,可以使用 ChainMap

示例代码如下:

from collections import ChainMap

dict1 = {'name': 'Alice', 'age': 30}
dict2 = {'city': 'New York', 'country': 'USA'}

combined_dict = ChainMap(dict1, dict2)
value1 = combined_dict['name']
value2 = combined_dict['city']
print(value1)  
print(value2)  

在上述代码中,首先从 collections 模块导入 ChainMap。然后定义了两个字典 dict1dict2。接着使用 ChainMap 将这两个字典组合成一个 combined_dict。通过 combined_dict['name'] 可以访问 dict1 中的值 'Alice',通过 combined_dict['city'] 可以访问 dict2 中的值 'New York',并将它们打印出来。

ChainMap中键冲突的处理

当多个字典中有相同的键时,ChainMap 会按照字典传入的顺序查找键值对。也就是说,先在第一个字典中查找,如果找到就返回对应的值,不再继续查找后续字典;如果第一个字典中没有找到,才会在第二个字典中查找,以此类推。

例如:

from collections import ChainMap

dict1 = {'name': 'Alice', 'age': 30}
dict2 = {'name': 'Bob', 'city': 'New York'}

combined_dict = ChainMap(dict1, dict2)
value = combined_dict['name']
print(value)  

在这个示例中,dict1dict2 都有 'name' 键,但由于 dict1ChainMap 中排在前面,所以 combined_dict['name'] 返回的是 dict1'name' 对应的值 'Alice'

使用字典推导式访问和处理值

字典推导式是一种简洁的创建字典的方式,同时也可以用于对字典的值进行访问和处理。

基本的字典推导式语法

字典推导式的基本语法如下:

{key_expression: value_expression for item in iterable}

其中,key_expression 是生成字典键的表达式,value_expression 是生成字典值的表达式,item 是从 iterable 中迭代出的元素。

例如,我们有一个列表 numbers = [1, 2, 3, 4, 5],想要创建一个字典,键是列表中的数字,值是数字的平方,可以使用字典推导式:

numbers = [1, 2, 3, 4, 5]
squared_dict = {num: num ** 2 for num in numbers}
print(squared_dict)  

在上述代码中,通过字典推导式,遍历 numbers 列表,对于每个数字 num,生成键为 num,值为 num ** 2 的字典元素,最终创建并打印出 squared_dict

使用字典推导式访问和处理现有字典的值

我们还可以对现有字典的值进行处理并生成新的字典。例如,有一个字典 my_dict = {'a': 1, 'b': 2, 'c': 3},想要创建一个新字典,键不变,值是原来值的两倍,可以这样做:

my_dict = {'a': 1, 'b': 2, 'c': 3}
new_dict = {key: value * 2 for key, value in my_dict.items()}
print(new_dict)  

在上述代码中,通过 my_dict.items() 遍历 my_dict 的键值对,对于每个键值对,生成键为原来的键,值为原来值两倍的新字典元素,最终创建并打印出 new_dict

这种方式在需要对字典的值进行批量处理时非常方便,代码简洁且高效。

使用operator模块访问字典值

operator 模块提供了一系列与Python内置操作符对应的函数,在访问字典值时,operator 模块中的一些函数也能发挥作用。

使用itemgetter获取字典值

itemgetter 函数可以创建一个可调用对象,用于从可迭代对象(如字典)中获取指定的元素。

示例代码如下:

from operator import itemgetter

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
get_name = itemgetter('name')
value = get_name(my_dict)
print(value)  

在上述代码中,首先从 operator 模块导入 itemgetter。然后使用 itemgetter('name') 创建了一个可调用对象 get_name,这个对象专门用于获取字典中 'name' 键对应的值。接着调用 get_name(my_dict),获取并打印出 'Alice'

itemgetter 还可以接受多个参数,用于获取多个键对应的值,返回一个包含这些值的元组。

例如:

from operator import itemgetter

my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
get_name_age = itemgetter('name', 'age')
values = get_name_age(my_dict)
print(values)  

在这个示例中,itemgetter('name', 'age') 创建的可调用对象 get_name_age 可以获取字典中 'name''age' 键对应的值,并以元组的形式返回,最后打印出 ('Alice', 30)

使用attrgetter间接访问字典值(当值为对象时)

当字典的值是对象,并且对象有属性时,attrgetter 函数可以用于获取对象的属性值。假设我们有一个字典,其中的值是自定义类的实例,类中有属性。

示例代码如下:

from operator import attrgetter


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


my_dict = {'person1': Person('Alice', 30)}
get_name = attrgetter('name')
value = get_name(my_dict['person1'])
print(value)  

在上述代码中,定义了一个 Person 类,然后创建了一个字典 my_dict,其中 'person1' 键对应的值是 Person 类的实例。通过 attrgetter('name') 创建一个可调用对象 get_name,用于获取 Person 实例的 name 属性值。最后调用 get_name(my_dict['person1']) 获取并打印出 'Alice'

高级技巧:使用元组作为字典键来访问值

在Python中,字典的键可以是不可变类型,元组就是一种常用的不可变类型。使用元组作为字典键可以创建更复杂的数据结构,并且以独特的方式访问值。

基本示例

假设我们有一个场景,需要记录不同城市不同年份的人口数量,就可以使用元组作为字典键。

示例代码如下:

population_dict = {
    ('New York', 2020): 8804190,
    ('Los Angeles', 2020): 3990456,
    ('New York', 2019): 8336817
}
value = population_dict[('New York', 2020)]
print(value)  

在上述代码中,population_dict 字典的键是由城市名称和年份组成的元组。通过 population_dict[('New York', 2020)] 可以获取 ('New York', 2020) 这个键对应的值 8804190 并打印出来。

利用元组的部分元素进行值的查找(高级用法)

有时候,我们可能只知道元组键中的部分元素,想要查找符合部分条件的值。例如,只知道城市名称,想获取该城市所有年份的人口数据。虽然不能直接像常规键那样部分匹配,但可以通过遍历字典来实现类似功能。

示例代码如下:

population_dict = {
    ('New York', 2020): 8804190,
    ('Los Angeles', 2020): 3990456,
    ('New York', 2019): 8336817
}
city = 'New York'
for key, value in population_dict.items():
    if key[0] == city:
        print(f'{city}在{key[1]}年的人口是{value}')  

在这段代码中,通过遍历 population_dict 的键值对,判断键的第一个元素(城市名称)是否与指定的城市名称 'New York' 相等。如果相等,则打印出该城市对应年份的人口数据。

通过以上多种方式,我们可以根据不同的需求和场景,灵活地在Python中访问字典的值。每种方式都有其特点和适用场景,熟练掌握这些方法能够让我们在处理字典数据时更加高效和便捷。