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

Python字典基础概念解析

2021-06-043.8k 阅读

什么是Python字典

在Python编程的世界里,字典(Dictionary)是一种非常重要的数据结构。它与我们日常生活中使用的字典有着相似之处,用于存储一系列的键值对(key - value pairs)。简单来说,字典就像是一个大的容器,你可以通过一个特定的“键”来快速找到与之对应的值。例如,在一个电话簿中,人名就相当于“键”,电话号码则是与之对应的“值”。通过人名,我们能够快速查找相应的电话号码。

在Python中,字典是无序的集合,这意味着其中的键值对并没有特定的顺序。这与列表(List)不同,列表是有序的集合。字典用花括号 {} 来表示,键值对之间用逗号 , 分隔,键和值之间使用冒号 : 连接。下面是一个简单的字典示例:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}

在这个字典 my_dict 中,'name''age''city' 是键,而 'Alice'25'New York' 分别是对应的值。

字典的创建

直接使用花括号创建

最常见的创建字典的方式就是像上面示例那样,直接使用花括号 {} 并在其中定义键值对。例如:

student = {'name': 'Bob', 'grade': 'A', 'course': 'Math'}

使用dict()函数创建

Python还提供了 dict() 函数来创建字典。可以通过传递一系列的键值对参数来创建字典。例如:

person = dict(name='Charlie', job='Engineer', salary=5000)

另外,dict() 函数还可以接受可迭代对象来创建字典。例如,可以传递一个包含元组的列表,每个元组包含一个键和一个值:

data = [('key1', 'value1'), ('key2', 'value2')]
new_dict = dict(data)
print(new_dict)

字典的基本操作

访问字典的值

要访问字典中的值,我们需要使用对应的键。例如,对于前面定义的 my_dict 字典:

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

运行上述代码,会分别输出 Alice25

然而,如果使用一个不存在的键来访问值,Python会抛出一个 KeyError 异常。例如:

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

上述代码会引发 KeyError: 'phone' 错误,因为字典中不存在 'phone' 这个键。

为了避免这种错误,可以使用 get() 方法。get() 方法在键不存在时,不会抛出异常,而是返回 None 或者你指定的默认值。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
print(my_dict.get('phone'))  
print(my_dict.get('phone', 'Not found'))  

第一个 get() 调用会返回 None,第二个 get() 调用会返回 Not found

修改字典的值

要修改字典中某个键对应的值,只需通过键来引用它并赋予新的值。例如:

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

上述代码会将 my_dict'age' 对应的值从 25 修改为 26

添加新的键值对

如果要向字典中添加新的键值对,同样通过键来引用并赋予值。如果这个键在字典中不存在,就会创建一个新的键值对。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
my_dict['phone'] = '123 - 456 - 7890'
print(my_dict)  

上述代码会在 my_dict 中添加一个新的键值对 'phone': '123 - 456 - 7890'

删除键值对

可以使用 del 语句来删除字典中的键值对。例如:

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

上述代码会删除 my_dict'city' 对应的键值对。

另外,字典还提供了 pop() 方法,它不仅会删除指定键的键值对,还会返回被删除的值。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
city = my_dict.pop('city')
print(city)  
print(my_dict)  

上述代码中,pop('city') 会删除 'city' 键值对,并返回 'New York'

字典的遍历

遍历键

可以使用 for 循环直接遍历字典,默认情况下会遍历字典的键。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
for key in my_dict:
    print(key)

上述代码会依次输出 nameagecity

也可以使用 keys() 方法来明确地获取字典的键视图,并进行遍历:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
for key in my_dict.keys():
    print(key)

keys() 方法返回的是一个可迭代的视图对象,它会动态反映字典的变化。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
keys_view = my_dict.keys()
print(list(keys_view))  
my_dict['phone'] = '123 - 456 - 7890'
print(list(keys_view))  

第一次输出 ['name', 'age', 'city'],第二次输出 ['name', 'age', 'city', 'phone'],因为字典发生了变化,键视图也随之更新。

遍历值

要遍历字典的值,可以使用 values() 方法。例如:

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

上述代码会依次输出 Alice25New York

同样,values() 方法返回的也是一个可迭代的视图对象,会动态反映字典的变化。

遍历键值对

使用 items() 方法可以同时遍历字典的键和值。items() 方法返回一个包含所有键值对的可迭代视图对象,每个元素是一个包含键和值的元组。例如:

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

上述代码会输出:

name: Alice
age: 25
city: New York

字典的嵌套

字典可以嵌套使用,即一个字典的值可以是另一个字典。例如,假设我们要存储一个班级学生的信息,每个学生又有自己的详细信息,就可以使用嵌套字典:

classroom = {
   'student1': {
        'name': 'Alice',
         'age': 20,
         'grade': 'A'
    },
   'student2': {
        'name': 'Bob',
         'age': 21,
         'grade': 'B'
    }
}

要访问嵌套字典中的值,需要使用多层键引用。例如,要获取 student1grade

classroom = {
   'student1': {
        'name': 'Alice',
         'age': 20,
         'grade': 'A'
    },
   'student2': {
        'name': 'Bob',
         'age': 21,
         'grade': 'B'
    }
}
print(classroom['student1']['grade'])  

上述代码会输出 A

字典的方法

clear()方法

clear() 方法用于清空字典中的所有键值对,将字典变为一个空字典。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
my_dict.clear()
print(my_dict)  

上述代码会输出 {}

copy()方法

copy() 方法用于创建字典的一个浅拷贝。浅拷贝意味着新字典和原字典中的嵌套对象(如列表、字典等)仍然是共享的。例如:

original_dict = {'name': 'Alice', 'hobbies': ['reading', 'painting']}
copied_dict = original_dict.copy()
print(copied_dict)  
original_dict['hobbies'].append('swimming')
print(copied_dict)  

上述代码中,修改原字典中 hobbies 列表,拷贝的字典中 hobbies 列表也会跟着改变,因为它们共享这个列表对象。

fromkeys()方法

fromkeys() 方法用于创建一个新字典,其中包含指定的键,并为每个键赋予相同的初始值。例如:

keys = ['key1', 'key2', 'key3']
new_dict = dict.fromkeys(keys, 0)
print(new_dict)  

上述代码会创建一个新字典,键为 ['key1', 'key2', 'key3'],每个键对应的值都是 0

popitem()方法

popitem() 方法用于随机移除并返回字典中的一个键值对(在Python 3.7及以上版本中,移除的是最后插入的键值对)。例如:

my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
item = my_dict.popitem()
print(item)  
print(my_dict)  

上述代码会随机(或按最后插入顺序)移除一个键值对,并输出移除的键值对和修改后的字典。

setdefault()方法

setdefault() 方法用于获取指定键的值,如果键不存在,则将键添加到字典中,并赋予指定的默认值(如果未指定默认值,则默认为 None)。例如:

my_dict = {'name': 'Alice', 'age': 25}
value = my_dict.setdefault('city', 'Unknown')
print(value)  
print(my_dict)  

上述代码中,setdefault('city', 'Unknown') 会先尝试获取 'city' 的值,由于键不存在,会添加 'city': 'Unknown' 键值对,并返回 'Unknown'

update()方法

update() 方法用于将另一个字典的键值对更新到当前字典中。如果有相同的键,则覆盖原有的值。例如:

dict1 = {'name': 'Alice', 'age': 25}
dict2 = {'age': 26, 'city': 'New York'}
dict1.update(dict2)
print(dict1)  

上述代码会将 dict2 中的键值对更新到 dict1 中,age 的值被更新为 26,并添加了 'city': 'New York' 键值对。

字典与其他数据结构的比较

字典与列表

  • 顺序性:列表是有序的,每个元素有其固定的索引位置;而字典是无序的,通过键来访问值。
  • 访问方式:列表通过整数索引来访问元素,字典通过键来访问值。键可以是各种不可变类型(如字符串、数字、元组等),这使得字典在查找元素时更加灵活。
  • 应用场景:列表适合存储有序的、同类型的数据集合,比如一个班级学生的成绩列表;字典适合存储具有映射关系的数据,比如学生姓名和成绩的对应关系。

字典与集合

  • 数据结构类型:集合是无序的、唯一元素的集合,主要用于成员测试和消除重复元素;字典是键值对的集合,重点在于通过键来查找值。
  • 元素类型:集合中的元素必须是不可变类型,字典的键也必须是不可变类型,但值可以是任意类型。
  • 应用场景:集合常用于判断元素是否存在、求交集并集等操作;字典则用于需要通过某个标识(键)来快速获取相关数据(值)的场景。

字典在实际编程中的应用

统计单词出现次数

假设我们有一个文本,需要统计每个单词出现的次数,字典就非常适合这个任务。例如:

text = "this is a sample text. this text is for testing."
word_count = {}
words = text.split()
for word in words:
    if word in word_count:
        word_count[word] += 1
    else:
        word_count[word] = 1
print(word_count)  

上述代码会统计文本中每个单词出现的次数,并将结果存储在 word_count 字典中。

配置文件解析

在开发应用程序时,常常会使用配置文件来存储一些参数。可以将配置文件中的参数解析为字典,方便在程序中使用。例如,假设配置文件内容如下:

[database]
host = localhost
port = 3306
user = root
password = password

可以使用 configparser 模块来解析这个配置文件,并转换为字典:

import configparser

config = configparser.ConfigParser()
config.read('config.ini')
db_config = dict(config.items('database'))
print(db_config)  

上述代码会将配置文件中 database 部分的参数解析为字典 db_config

作为函数参数传递

字典可以很方便地作为函数参数传递,特别是当函数需要接收多个参数时。例如:

def connect_to_database(config):
    host = config.get('host', 'localhost')
    port = int(config.get('port', 3306))
    user = config.get('user', 'root')
    password = config.get('password', '')
    # 这里进行数据库连接操作
    print(f'Connecting to {host}:{port} as {user}')

db_config = {
    'host': '192.168.1.100',
    'port': 3307,
    'user': 'admin',
    'password': 'adminpass'
}
connect_to_database(db_config)  

上述代码通过传递字典 db_config 作为函数参数,使得函数 connect_to_database 可以灵活地使用不同的数据库配置。

字典使用的注意事项

键的不可变性

字典的键必须是不可变类型,如字符串、数字、元组等。不能使用列表、字典等可变类型作为键,否则会导致 TypeError。例如:

my_dict = {[1, 2]: 'value'}  

上述代码会引发 TypeError: unhashable type: 'list' 错误,因为列表是不可哈希的(不可变类型才能哈希),不能作为字典的键。

字典的无序性

由于字典是无序的,在遍历字典时,键值对的顺序可能与插入顺序不同,并且每次遍历的顺序也不一定相同。如果需要保持顺序,可以使用 collections.OrderedDict(在Python 3.7及以上版本中,普通字典已经默认保持插入顺序)。例如:

from collections import OrderedDict

ordered_dict = OrderedDict()
ordered_dict['a'] = 1
ordered_dict['b'] = 2
ordered_dict['c'] = 3

for key, value in ordered_dict.items():
    print(f'{key}: {value}')

上述代码会按照插入顺序输出键值对。

字典的内存占用

字典在存储数据时,由于需要维护键的哈希表等数据结构,相比其他简单的数据结构,可能会占用更多的内存。特别是当字典中包含大量键值对时,需要考虑内存的使用情况。如果内存空间有限,可以考虑优化数据结构或采用其他存储方式。

在Python编程中,字典是一种功能强大且使用广泛的数据结构。深入理解字典的概念、操作和应用场景,能够帮助我们编写出更加高效、灵活的代码。无论是简单的数据统计,还是复杂的应用程序配置管理,字典都能发挥重要作用。同时,注意字典使用过程中的各种细节和注意事项,能够避免许多常见的编程错误。希望通过本文的介绍,你对Python字典有了更全面、更深入的理解,并能在实际编程中熟练运用它。