最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python字典創(chuàng)建、訪問、修改、刪除及遍歷的完整指南

 更新時(shí)間:2026年05月31日 09:31:27   作者:念恒12306  
在編程中,我們經(jīng)常需要建立一種映射關(guān)系:比如通過學(xué)號(hào)找到學(xué)生姓名,通過商品編號(hào)找到價(jià)格,Python?的字典(dict)正是為此而生,因此本文給大家詳細(xì)介紹了Python字典創(chuàng)建、訪問、修改、刪除及遍歷的完整指南,需要的朋友可以參考下

在編程中,我們經(jīng)常需要建立一種“映射關(guān)系”:比如通過學(xué)號(hào)找到學(xué)生姓名,通過商品編號(hào)找到價(jià)格。Python 的字典(dict)正是為此而生。它是一種可變無序(Python 3.7+ 保持插入順序)、鍵唯一的映射類型,通過哈希表實(shí)現(xiàn) O(1) 的平均查找速度。

1. 字典是什么?

字典是鍵值對(duì)(key-value pair)的集合。每個(gè)鍵對(duì)應(yīng)一個(gè)值,鍵必須是不可變類型(如字符串、數(shù)字、元組),值可以是任意類型。

# 一個(gè)簡(jiǎn)單的字典:學(xué)生信息
student = {"name": "張三", "age": 20, "major": "計(jì)算機(jī)"}
print(student["name"])   # 輸出:張三

代碼解析

  • student = {"name": "張三", "age": 20, "major": "計(jì)算機(jī)"}:創(chuàng)建一個(gè)名為 student 的字典,包含三個(gè)鍵值對(duì)。鍵 "name" 對(duì)應(yīng)值 "張三",鍵 "age" 對(duì)應(yīng)整數(shù) 20,鍵 "major" 對(duì)應(yīng)字符串 "計(jì)算機(jī)"。
  • print(student["name"]):通過方括號(hào)語法使用鍵 "name" 訪問其對(duì)應(yīng)的值,輸出 "張三"

核心特性

  • 鍵唯一:同一個(gè)字典中不能有重復(fù)的鍵。如果重復(fù)賦值,后一個(gè)會(huì)覆蓋前一個(gè)。
  • 可變:可以增、刪、改鍵值對(duì)。
  • 無序 → 有序:在 Python 3.6 之前是無序的,3.7 之后插入順序被保留(作為語言特性)。這意味著遍歷字典時(shí)會(huì)按照鍵值對(duì)添加的順序返回。
  • 高效查找:基于哈希表,平均時(shí)間復(fù)雜度 O(1)。

C/C++ 聯(lián)動(dòng)

  • C++ 中實(shí)現(xiàn)類似映射可以使用 std::unordered_map<Key, Value>(哈希表,平均 O(1))或 std::map<Key, Value>(紅黑樹,O(log n))。Python 字典的底層就是哈希表,因此與 unordered_map 更相似。
  • C++ 示例:
#include <unordered_map>
#include <string>
std::unordered_map<std::string, int> student = {{"name", 20}, {"age", 20}};
// 訪問:student["name"] 或 student.at("name")
  • 區(qū)別:Python 字典的鍵可以是任意不可變類型(如字符串、數(shù)字、元組),而 C++ unordered_map 的鍵類型需要在編譯期確定,且必須提供哈希函數(shù)(內(nèi)置類型已提供)。

2. 創(chuàng)建字典

2.1 使用花括號(hào){}

# 空字典
empty = {}

# 帶初始值
person = {"name": "李四", "age": 25}

代碼解析

  • empty = {}:一對(duì)花括號(hào)創(chuàng)建了一個(gè)空字典。注意:空花括號(hào)是字典,不是集合(集合需要用 set() 創(chuàng)建空集)。
  • person = {"name": "李四", "age": 25}:花括號(hào)內(nèi)用逗號(hào)分隔多個(gè)鍵值對(duì),每個(gè)鍵值對(duì)格式為 "key": value。鍵可以是字符串、數(shù)字等不可變類型,值任意。

2.2 使用dict()構(gòu)造函數(shù)

# 從關(guān)鍵字參數(shù)創(chuàng)建
person = dict(name="王五", age=30)

# 從可迭代對(duì)象(如列表的元組對(duì))創(chuàng)建
items = [("name", "趙六"), ("age", 28)]
person = dict(items)   # {'name': '趙六', 'age': 28}

# 空字典
empty = dict()

代碼解析

  • dict(name="王五", age=30):關(guān)鍵字參數(shù)形式,鍵名會(huì)被當(dāng)作字符串(不需要引號(hào)),這是創(chuàng)建字典的簡(jiǎn)潔方式。注意:鍵名必須是合法的變量名(不能以數(shù)字開頭,不能含空格)。
  • dict(items)items 是一個(gè)列表,每個(gè)元素是一個(gè)包含兩個(gè)元素的元組(或列表)。dict() 將每個(gè)元組的第一個(gè)元素作為鍵,第二個(gè)作為值,構(gòu)造字典。
  • dict():無參數(shù)調(diào)用創(chuàng)建一個(gè)空字典,與 {} 等效。

C/C++ 聯(lián)動(dòng)

  • C++ 中初始化 unordered_map 可以使用初始化列表:
std::unordered_map<std::string, int> person = {{"name", 30}, {"age", 25}};
  • 從鍵值對(duì)序列構(gòu)造:可以遍歷 vector 并插入,沒有 Python 的 dict(iterable) 那樣直接。

2.3 使用zip()組合兩個(gè)序列

keys = ["a", "b", "c"]
values = [1, 2, 3]
d = dict(zip(keys, values))   # {'a': 1, 'b': 2, 'c': 3}

代碼解析

  • zip(keys, values):將兩個(gè)列表打包成一系列元組:[('a',1), ('b',2), ('c',3)]。
  • dict(...):將這個(gè)元組列表轉(zhuǎn)換為字典。如果兩個(gè)序列長(zhǎng)度不同,zip 會(huì)以較短的為準(zhǔn)。

2.4 字典推導(dǎo)式(見7 )

3. 訪問字典

3.1 通過鍵訪問([])

d = {"apple": 5, "banana": 3}
print(d["apple"])   # 5
# print(d["orange"])  # KeyError: 'orange'

代碼解析

  • d["apple"]:使用方括號(hào)和鍵名獲取對(duì)應(yīng)的值。如果鍵不存在,會(huì)拋出 KeyError 異常,程序終止(除非捕獲異常)。因此這種方法適合確定鍵一定存在的場(chǎng)景。

C/C++ 聯(lián)動(dòng)

  • C++ 中 unordered_map 的 operator[] 行為與 Python 不同:如果鍵不存在,它會(huì)插入一個(gè)默認(rèn)構(gòu)造的值并返回引用,不會(huì)拋出異常。例如:
std::unordered_map<std::string, int> d;
int val = d["orange"];   // 插入鍵 "orange" 并值為 0,val = 0
  • 若希望像 Python 一樣不插入新鍵,可以使用 d.find(key) 或 d.at(key)at 會(huì)拋出 std::out_of_range)。

3.2 使用get()方法(安全訪問)

print(d.get("orange"))        # None(不報(bào)錯(cuò))
print(d.get("orange", 0))     # 0(指定默認(rèn)值)

代碼解析

  • d.get("orange"):嘗試獲取鍵 "orange" 的值。如果鍵不存在,返回 None(不會(huì)拋出異常)。適合不確定鍵是否存在的場(chǎng)景。
  • d.get("orange", 0):第二個(gè)參數(shù)指定默認(rèn)值,當(dāng)鍵不存在時(shí)返回 0 而不是 None。

C/C++ 聯(lián)動(dòng):C++ 中無直接對(duì)應(yīng)的 get 方法,通常使用 find 并檢查迭代器:

auto it = d.find("orange");
int val = (it != d.end()) ? it->second : 0;

3.3 獲取所有鍵、值、鍵值對(duì)

d = {"a": 1, "b": 2}
print(d.keys())     # dict_keys(['a', 'b'])
print(d.values())   # dict_values([1, 2])
print(d.items())    # dict_items([('a', 1), ('b', 2)])

代碼解析

  • d.keys()、d.values()、d.items() 返回的是視圖對(duì)象(view)。這些視圖動(dòng)態(tài)反映字典的變化,如果字典后續(xù)修改,視圖也會(huì)相應(yīng)改變。
  • 視圖對(duì)象支持迭代,可以用于 for 循環(huán)。例如 for k in d.keys():。
  • 在 Python 3 中,視圖不是列表,但可以轉(zhuǎn)換為列表:list(d.keys())。

C/C++ 聯(lián)動(dòng):C++ 中獲取所有鍵需要手動(dòng)遍歷或使用 range-based for:

for (const auto& pair : d) {
    // pair.first 是鍵,pair.second 是值
}

3.4 setdefault()—— 獲取值,若鍵不存在則設(shè)置默認(rèn)值

d = {"a": 1}
v = d.setdefault("b", 100)   # 鍵 "b" 不存在,設(shè)置 d["b"]=100,并返回 100
print(d)   # {'a': 1, 'b': 100}
v2 = d.setdefault("a", 99)   # 鍵存在,返回原值 1,不修改

代碼解析

  • setdefault 先檢查鍵是否存在,如果存在則返回對(duì)應(yīng)的值;如果不存在,則插入 key: default 鍵值對(duì),并返回 default。這個(gè)方法常用于需要初始化缺失鍵的場(chǎng)景(比如構(gòu)建分組字典)。

C/C++ 聯(lián)動(dòng):C++ 中可以用 insert 配合 try_emplace 實(shí)現(xiàn)類似功能,但不如 Python 簡(jiǎn)潔。

4. 修改字典

4.1 添加或更新鍵值對(duì)

d = {}
d["name"] = "張三"   # 添加
d["age"] = 25        # 添加
d["age"] = 26        # 更新

代碼解析

  • 當(dāng)方括號(hào)內(nèi)的鍵不存在時(shí),該賦值操作會(huì)在字典中添加一個(gè)新的鍵值對(duì)。
  • 當(dāng)鍵已存在時(shí),賦值會(huì)更新該鍵對(duì)應(yīng)的值。

 C/C++ 聯(lián)動(dòng):C++ 中 unordered_map 的 operator[] 同樣可添加或更新,但區(qū)別在于:如果鍵不存在,會(huì)插入默認(rèn)構(gòu)造的值再賦值。例如 d["age"] = 25 會(huì)先檢查,若不存在則插入 int()(即0),再賦值為 25。因此 C++ 中不能直接用 [] 判斷是否存在。

4.2 update()—— 合并另一個(gè)字典或可迭代對(duì)象

d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
d1.update(d2)        # d1 變?yōu)?{'a': 1, 'b': 3, 'c': 4}
# 也支持關(guān)鍵字參數(shù):d1.update(c=5, d=6)

代碼解析

  • update() 接受一個(gè)字典或鍵值對(duì)的可迭代對(duì)象(如列表的元組)。它會(huì)將參數(shù)中的每個(gè)鍵值對(duì)合并到原字典中,如果鍵已存在則覆蓋,如果不存在則添加。
  • 常見的用法:d1.update(d2) 相當(dāng)于 for k, v in d2.items(): d1[k] = v。

C/C++ 聯(lián)動(dòng):C++ 中合并兩個(gè) unordered_map 需要循環(huán)插入,沒有直接方法。

5. 刪除字典元素

5.1 del語句

d = {"a": 1, "b": 2, "c": 3}
del d["b"]           # 刪除鍵為 "b" 的項(xiàng)
# del d["x"]         # KeyError 若鍵不存在

代碼解析

  • del d["b"] 刪除字典中鍵為 "b" 的鍵值對(duì)。如果鍵不存在,拋出 KeyError。
  • del 也可以刪除整個(gè)字典變量:del d,之后字典對(duì)象被回收。

5.2 pop()—— 刪除并返回指定鍵的值

value = d.pop("a")   # 返回 1,d 變?yōu)?{'c': 3}
# d.pop("x")         # KeyError
d.pop("x", None)     # 不報(bào)錯(cuò),返回 None

代碼解析

  • pop(key) 刪除指定鍵并返回對(duì)應(yīng)的值。如果鍵不存在,拋出 KeyError。
  • pop(key, default) 提供默認(rèn)值,當(dāng)鍵不存在時(shí)返回 default,不會(huì)拋出異常。

C/C++ 聯(lián)動(dòng):C++ 中 unordered_map 的 erase 方法刪除鍵并返回被刪除元素的數(shù)量(0或1),不返回值。要獲取值需先 find

5.3 popitem()—— 刪除并返回最后一個(gè)鍵值對(duì)(Python 3.7+ 按 LIFO)

d = {"a": 1, "b": 2}
key, value = d.popitem()   # 返回 ('b', 2)(插入順序的最后一個(gè))

代碼解析

  • 在 Python 3.7+ 中,popitem() 刪除并返回字典中最后插入的鍵值對(duì)(后進(jìn)先出)。在 3.6 之前,由于字典無序,它返回任意一個(gè)鍵值對(duì)。
  • 返回值為一個(gè)元組 (key, value),可直接拆包。

5.4 clear()—— 清空字典

d.clear()            # {}

代碼解析:刪除字典中所有鍵值對(duì),使字典變?yōu)榭兆值?nbsp;{}

6. 遍歷字典

6.1 遍歷鍵

for key in d:
    print(key)
# 或 for key in d.keys():

代碼解析:直接使用 for key in d 是遍歷字典最常用的方式,每次迭代獲取一個(gè)鍵。也可以用 d.keys() 顯式獲取鍵視圖。

6.2 遍歷值

for value in d.values():
    print(value)

代碼解析d.values() 返回值的視圖,用于遍歷所有值。注意:值可能重復(fù),且無法直接通過值找到對(duì)應(yīng)的鍵(除非反向查找)。

6.3 同時(shí)遍歷鍵和值

for key, value in d.items():
    print(key, value)

代碼解析d.items() 返回鍵值對(duì)視圖,每個(gè)元素是一個(gè) (key, value) 元組。通過拆包可以直接獲取鍵和值。

6.4 帶條件或轉(zhuǎn)換的遍歷

# 只打印值大于 10 的項(xiàng)
for k, v in d.items():
    if v > 10:
        print(k, v)

代碼解析:可以在循環(huán)體內(nèi)加入條件判斷,過濾出滿足條件的鍵值對(duì)。

7. 字典推導(dǎo)式

與列表推導(dǎo)式類似,用于快速生成字典。

# 平方映射
squares = {x: x**2 for x in range(5)}   # {0:0, 1:1, 2:4, 3:9, 4:16}

代碼解析:基本語法 {key_expr: value_expr for variable in iterable}。這里 x 是迭代變量,鍵是 x,值是 x**2。

# 條件過濾:只保留偶數(shù)鍵
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}

代碼解析:在推導(dǎo)式末尾加上 if 子句,只對(duì)滿足條件的 x 生成鍵值對(duì)。

# 交換鍵和值
original = {"a": 1, "b": 2}
inverted = {v: k for k, v in original.items()}   # {1: 'a', 2: 'b'}

代碼解析:遍歷原字典的 items(),將鍵和值互換作為新字典的鍵值對(duì)。注意:如果原字典有重復(fù)的值,后面的會(huì)覆蓋前面的,因?yàn)殒I必須唯一。

8. 嵌套字典

字典的值可以是另一個(gè)字典,用于表示層次化數(shù)據(jù)。

students = {
    "S001": {"name": "Alice", "score": 85},
    "S002": {"name": "Bob", "score": 92}
}
print(students["S001"]["name"])   # Alice

代碼解析

  • 外層字典的鍵是學(xué)號(hào),值是一個(gè)內(nèi)層字典(包含 name 和 score)。
  • 訪問時(shí)使用兩層方括號(hào):先通過學(xué)號(hào)獲取內(nèi)層字典,再通過 "name" 獲取姓名。

安全訪問嵌套:逐層使用 get 或使用 try-except。

9. 字典的常用方法匯總

方法說明
get(key, default)安全獲取值,鍵不存在時(shí)返回默認(rèn)值(默認(rèn) None)。
setdefault(key, default)如果鍵存在,返回其值;否則設(shè)置 d[key]=default 并返回 default。
update([other])用另一個(gè)字典或鍵值對(duì)序列更新當(dāng)前字典。
keys()返回所有鍵的視圖。
values()返回所有值的視圖。
items()返回所有 (鍵, 值) 對(duì)的視圖。
pop(key, default)刪除指定鍵并返回其值,若不存在返回 default(若未提供則 KeyError)。
popitem()刪除并返回最后一個(gè)插入的鍵值對(duì)(Python 3.7+)。
clear()清空字典。
copy()淺拷貝。
fromkeys(iterable, value)類方法,從可迭代對(duì)象創(chuàng)建字典,所有值初始為 value。

10. 字典的性能與底層原理

10.1 哈希表

Python 字典底層使用哈希表(hash table)。每個(gè)鍵通過哈希函數(shù)計(jì)算出一個(gè)整數(shù)索引,用于快速定位存儲(chǔ)位置。因此查找、插入、刪除的平均時(shí)間復(fù)雜度為 O(1),但最壞情況(哈希沖突嚴(yán)重)可能退化為 O(n)。Python 通過開放地址法和偽隨機(jī)探測(cè)解決沖突,并自動(dòng)調(diào)整表的大?。╮ehash)來維持高效。

C/C++ 聯(lián)動(dòng)

  • C++ std::unordered_map 同樣基于哈希表,平均 O(1),最壞 O(n)。兩者都會(huì)在負(fù)載因子過高時(shí)自動(dòng) rehash。
  • C++ std::map 基于紅黑樹,時(shí)間復(fù)雜度 O(log n),但內(nèi)存占用相對(duì)穩(wěn)定,且鍵有序。
  • Python 字典的哈希函數(shù)對(duì)字符串和整數(shù)做了優(yōu)化,而 C++ 需要為自定義類型特化 std::hash。

10.2 鍵的要求

  • 鍵必須是可哈希的:即對(duì)象必須實(shí)現(xiàn) __hash__() 和 __eq__() 方法,且在其生命周期中哈希值不變。
  • 不可變類型(字符串、數(shù)字、元組)通??晒#涣斜?、字典、集合等可變對(duì)象不可哈希。
  • 元組中若包含可變對(duì)象,則該元組不可哈希。
# 合法鍵
d = {("a", 1): "tuple"}
# 非法鍵
# d = {["a", 1]: "list"}   # TypeError: unhashable type: 'list'

代碼解析

  • 元組 ("a", 1) 中的元素都是不可變類型,因此元組本身可哈希,可以作為鍵。
  • 列表 ["a", 1] 是可變的,不能作為鍵。

C/C++ 聯(lián)動(dòng):C++ 中 unordered_map 的鍵也需要可哈希。內(nèi)置類型已有標(biāo)準(zhǔn)哈希,自定義類型需要提供 hash 特化和 operator==。例如:

struct MyKey {
    int a;
    std::string b;
    bool operator==(const MyKey& other) const { return a==other.a && b==other.b; }
};
namespace std {
    template<> struct hash<MyKey> {
        size_t operator()(const MyKey& k) const {
            return hash<int>()(k.a) ^ (hash<string>()(k.b) << 1);
        }
    };
}

10.3 內(nèi)存占用

字典比列表占用更多內(nèi)存(約 2~3 倍),因?yàn)楣1硇枰A(yù)留額外空間。

11. 擴(kuò)展:collections 模塊中的字典變種

11.1 defaultdict—— 帶默認(rèn)工廠的字典

當(dāng)訪問不存在的鍵時(shí),自動(dòng)創(chuàng)建默認(rèn)值,避免 KeyError

from collections import defaultdict

# 默認(rèn)值為整數(shù) 0
dd = defaultdict(int)
dd["a"] += 1        # 不需要先檢查 "a" 是否存在
print(dd)           # {'a': 1}

代碼解析

  • defaultdict(int) 創(chuàng)建了一個(gè)默認(rèn)值為 int()(即 0)的字典。當(dāng)訪問不存在的鍵時(shí),自動(dòng)調(diào)用 int() 生成默認(rèn)值并插入。
  • dd["a"] += 1:由于 "a" 不存在,defaultdict 先設(shè)置 dd["a"] = 0,然后執(zhí)行 dd["a"] = 0 + 1
# 默認(rèn)值為空列表
dd2 = defaultdict(list)
dd2["group"].append(10)   # 自動(dòng)創(chuàng)建列表
print(dd2)                # {'group': [10]}

代碼解析list 工廠函數(shù)會(huì)在鍵缺失時(shí)創(chuàng)建一個(gè)空列表,然后可以安全地 append。

常見工廠intlistsetstr, 或自定義函數(shù)。

C/C++ 聯(lián)動(dòng):C++ 中 unordered_map 的 operator[] 在鍵不存在時(shí)會(huì)插入默認(rèn)值(值類型的默認(rèn)構(gòu)造)。例如 std::unordered_map<std::string, int> m; m["a"] += 1; 會(huì)先插入 int()(0),再自增。這與 defaultdict(int) 行為類似,但 Python 的 defaultdict 可以靈活指定任何工廠函數(shù)(如 list),而 C++ 的默認(rèn)構(gòu)造只適用于值類型。

11.2 Counter—— 計(jì)數(shù)器

用于統(tǒng)計(jì)可哈希元素出現(xiàn)的次數(shù)。

from collections import Counter

colors = ["red", "blue", "red", "green", "blue", "red"]
cnt = Counter(colors)
print(cnt)          # Counter({'red': 3, 'blue': 2, 'green': 1})
print(cnt["red"])   # 3
print(cnt.most_common(2))  # [('red', 3), ('blue', 2)]

代碼解析

  • Counter(colors) 遍歷列表,統(tǒng)計(jì)每個(gè)元素出現(xiàn)的次數(shù),返回一個(gè)類似字典的對(duì)象。
  • cnt["red"] 返回 'red' 出現(xiàn)的次數(shù)。對(duì)于不存在的鍵,返回 0(不報(bào)錯(cuò))。
  • most_common(2) 返回出現(xiàn)次數(shù)最多的前 2 個(gè)元素及其次數(shù),按降序排列。

C/C++ 聯(lián)動(dòng):C++ 中沒有 Counter 的直接對(duì)應(yīng),但可以用 unordered_map 實(shí)現(xiàn)計(jì)數(shù),再借助 vector 排序獲取最值。Python 的 Counter 更高級(jí),內(nèi)置了 most_common 等便捷方法。

11.3 OrderedDict—— 保持插入順序(Python 3.7+ 中普通 dict 已有序)

在 Python 3.6 之前,字典無序,OrderedDict 用于保持插入順序?,F(xiàn)在普通 dict 也保持順序,但 OrderedDict 還額外提供了 move_to_end() 等方法。

from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od.move_to_end("a")   # 將 "a" 移到末尾

代碼解析move_to_end(key, last=True) 將指定鍵移動(dòng)到末尾(如果 last=False 則移動(dòng)到開頭)。

 C/C++ 聯(lián)動(dòng):C++ 中保持插入順序沒有標(biāo)準(zhǔn)容器直接支持??梢允褂?nbsp;std::vector 配合 unordered_map 來記錄順序,或使用 boost::multi_index。Python 3.7+ 普通 dict 已有序,這是比 C++ 方便的特性。

11.4 ChainMap—— 將多個(gè)字典合并成一個(gè)視圖

用于查找時(shí)按順序搜索多個(gè)字典。

from collections import ChainMap
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
chain = ChainMap(d1, d2)
print(chain["b"])   # 從 d1 找到 2(取第一個(gè))

代碼解析

  • ChainMap(d1, d2) 創(chuàng)建了一個(gè)虛擬的合并字典,優(yōu)先查找 d1,如果 d1 中沒有再到 d2 中查找。
  • 修改 chain 會(huì)影響第一個(gè)字典 d1。

C/C++ 聯(lián)動(dòng):C++ 無直接對(duì)應(yīng),但可用多個(gè) map 和自定義搜索邏輯實(shí)現(xiàn)。

12. 字典與列表、元組的對(duì)比

特性字典列表元組
容器類型映射(鍵值對(duì))序列序列
有序性Python 3.7+ 插入有序有序有序
可變性可變可變不可變
索引方式鍵(不可變類型)整數(shù)索引整數(shù)索引
查找速度平均 O(1)O(n)O(n)
內(nèi)存占用較大中等略小于列表
典型用途關(guān)聯(lián)數(shù)據(jù)、快速查找有序序列不可變序列

13. 字典的應(yīng)用實(shí)戰(zhàn)

13.1 統(tǒng)計(jì)字符串中字符出現(xiàn)次數(shù)

text = "hello world"
freq = {}
for ch in text:
    if ch != " ":
        freq[ch] = freq.get(ch, 0) + 1
print(freq)

代碼解析

  • 遍歷字符串中的每個(gè)字符。
  • 跳過空格。
  • freq.get(ch, 0) 獲取字符當(dāng)前的計(jì)數(shù),如果不存在則返回 0,然后加 1 并賦值。
  • 更優(yōu)雅的方式:使用 Counter(text)

13.2 使用字典實(shí)現(xiàn)簡(jiǎn)單緩存(記憶化)

def fibonacci(n, cache={}):
    if n in cache:
        return cache[n]
    if n <= 1:
        return n
    cache[n] = fibonacci(n-1) + fibonacci(n-2)
    return cache[n]

代碼解析

  • 默認(rèn)參數(shù) cache={} 在函數(shù)定義時(shí)創(chuàng)建一次,后續(xù)調(diào)用會(huì)復(fù)用同一個(gè)字典對(duì)象(注意:可變默認(rèn)參數(shù)要小心使用,但在這里正好用來實(shí)現(xiàn)緩存)。
  • 每次計(jì)算 fibonacci(n) 時(shí),先檢查緩存,如果已有結(jié)果則直接返回,避免重復(fù)遞歸。

13.3 根據(jù)值排序字典

d = {"apple": 3, "banana": 1, "cherry": 2}
# 按值升序排序,得到鍵的列表
sorted_keys = sorted(d, key=d.get)           # ['banana', 'cherry', 'apple']
# 按值降序排序,得到鍵值對(duì)列表
sorted_items = sorted(d.items(), key=lambda x: x[1], reverse=True)

代碼解析

  • sorted(d, key=d.get)d.get 作為鍵函數(shù),對(duì)每個(gè)鍵獲取對(duì)應(yīng)的值,按值排序。結(jié)果返回鍵的列表。
  • sorted(d.items(), key=lambda x: x[1])d.items() 返回 (key, value) 元組,lambda x: x[1] 取元組的第二個(gè)元素(即值)作為排序依據(jù)。

13.4 合并兩個(gè)字典(Python 3.9+ 使用|)

d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
merged = d1 | d2        # {'a':1, 'b':3, 'c':4}
d1 |= d2                # 原地更新(Python 3.9+)

代碼解析

  • | 運(yùn)算符返回一個(gè)新字典,包含兩個(gè)字典的鍵值對(duì),重復(fù)鍵以右邊字典為準(zhǔn)。
  • |= 是原地操作,相當(dāng)于 d1.update(d2)。

C/C++ 聯(lián)動(dòng):C++ 中合并兩個(gè) unordered_map 無運(yùn)算符重載,需手動(dòng)循環(huán)插入。

14. 常見陷阱與注意事項(xiàng)

陷阱說明解決方案
使用可變對(duì)象作為鍵列表、字典等不可哈希,會(huì)報(bào)錯(cuò)改用元組或字符串
在遍歷字典時(shí)修改字典會(huì)導(dǎo)致 RuntimeError: dictionary changed size during iteration遍歷 list(d.keys()) 或 d.copy().items()
混淆 get 和 setdefaultsetdefault 會(huì)修改字典,get 不會(huì)按需選擇
認(rèn)為字典總是無序(舊代碼)Python 3.7+ 插入順序被保證,但依賴此特性的代碼需要最低版本使用 OrderedDict 若需嚴(yán)格兼容低版本
在 defaultdict 中傳遞可變對(duì)象工廠函數(shù)使用 list 而非 list(),傳遞可調(diào)用對(duì)象defaultdict(list) 正確,defaultdict(list()) 錯(cuò)誤
拷貝字典時(shí)使用 = 而非 copy二者指向同一對(duì)象,修改會(huì)互相影響淺拷貝用 d.copy(),深拷貝用 copy.deepcopy

C/C++ 聯(lián)動(dòng)

  • C++ 中同樣有遍歷時(shí)刪除導(dǎo)致迭代器失效的問題,通常使用 for (auto it = m.begin(); it != m.end(); ) { if (cond) it = m.erase(it); else ++it; }。
  • C++ 的 unordered_map 默認(rèn)不保留插入順序,如果需要順序需額外維護(hù)。

以上就是Python字典創(chuàng)建、訪問、修改、刪除及遍歷的完整指南的詳細(xì)內(nèi)容,更多關(guān)于Python字典操作指南的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

阿图什市| 安乡县| 濮阳市| 巨鹿县| 北辰区| 彭山县| 开阳县| 称多县| 安西县| 波密县| 临桂县| 蓬莱市| 故城县| 宝清县| 洛川县| 靖西县| 二连浩特市| 伊宁县| 清水县| 宜春市| 河西区| 深圳市| 依兰县| 雅安市| 德惠市| 康马县| 安吉县| 都江堰市| 二连浩特市| 金平| 南召县| 高台县| 井陉县| 定结县| 深泽县| 高要市| 广元市| 通渭县| 东宁县| 赣州市| 拉萨市|