当前位置:首页>python>Python全栈修炼之路 | 第5篇:字典与集合 —— 哈希的威力

Python全栈修炼之路 | 第5篇:字典与集合 —— 哈希的威力

  • 2026-06-28 01:15:05
Python全栈修炼之路 | 第5篇:字典与集合 —— 哈希的威力

作者:还怪好嘞 专栏:Python全栈修炼之路 标签:Python、字典、集合、哈希表、哈希冲突、时间复杂度


前言

字典(dict)和集合(set)是Python中最强大的数据结构之一。它们基于哈希表实现,提供了平均O(1)时间复杂度的查找、插入和删除操作。理解哈希原理,能让你更好地利用这些数据结构,写出更高效的代码。本文将深入剖析哈希表原理,并通过实战项目展示它们的强大威力。


一、知识点详解

1.1 字典基础操作

1.1.1 创建字典

# 1. 字面量创建empty = {}person = {"name""Alice""age"25"city""Beijing"}# 2. dict()构造函数from_pairs = dict([("a"1), ("b"2)])from_kwargs = dict(name="Bob", age=30)from_zip = dict(zip(["x""y""z"], [123]))# 3. 字典推导式squares = {x: x**2 for x in range(6)}# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 4. fromkeys() - 创建有默认值的字典keys = ["a""b""c"]= dict.fromkeys(keys, 0)  # {'a': 0, 'b': 0, 'c': 0}# 注意:默认值是同一个对象的引用!

1.1.2 访问与修改

# 访问元素person = {"name""Alice""age"25}print(person["name"])      # "Alice"# print(person["gender"])  # KeyError!# 安全访问print(person.get("gender"))        # Noneprint(person.get("gender""N/A")) # "N/A"# 设置值person["age"= 26         # 修改person["gender"= "female"  # 新增# setdefault - 不存在则设置默认值person.setdefault("country""China")  # 设置并返回值person.setdefault("name""Bob")       # 已存在,返回原值# update - 批量更新person.update({"age"27"job""Engineer"})person.update(age=28, hobby="Reading")

1.1.3 删除操作

person = {"name""Alice""age"25"city""Beijing"}# pop - 删除并返回值age = person.pop("age")  # 25# person.pop("gender")   # KeyError!# popitem - 删除并返回最后插入的项(Python 3.7+)item = person.popitem()  # ('city', 'Beijing')# del - 删除键值对del person["name"]# clear - 清空person.clear()  # {}

1.1.4 遍历字典

person = {"name""Alice""age"25"city""Beijing"}# 遍历键(默认)for key in person:    print(key)# 遍历键值对for key, value in person.items():    print(f"{key}{value}")# 遍历值for value in person.values():    print(value)# 遍历键for key in person.keys():    print(key)# 遍历时修改(需要复制)for key in list(person.keys()):    if key == "age":        del person[key]

1.2 字典方法速查表

方法
作用
时间复杂度
示例
d[key]
访问
O(1)
d["name"]
d.get(key, default)
安全访问
O(1)
d.get("x", 0)
d[key] = value
设置
O(1)
d["x"] = 1
del d[key]
删除
O(1)
del d["x"]
d.pop(key)
删除并返回
O(1)
d.pop("x")
d.popitem()
删除最后项
O(1)
d.popitem()
d.update(other)
批量更新
O(k)
d.update({"a":1})
d.keys()
返回键视图
O(1)
list(d.keys())
d.values()
返回值视图
O(1)
list(d.values())
d.items()
返回项视图
O(1)
list(d.items())
key in d
成员判断
O(1)
"x" in d

1.3 高级字典类型

1.3.1 defaultdict —— 自动默认值

from collections import defaultdict# 基本用法# 当访问不存在的键时,自动调用工厂函数创建默认值counts = defaultdict(int)      # 默认0lists = defaultdict(list)       # 默认[]sets = defaultdict(set)         # 默认set()# 词频统计words = ["apple""banana""apple""cherry""banana""apple"]for word in words:    counts[word] += 1  # 无需检查key是否存在print(dict(counts))  # {'apple': 3, 'banana': 2, 'cherry': 1}# 分组pairs = [("a"1), ("b"2), ("a"3), ("b"4)]grouped = defaultdict(list)for key, value in pairs:    grouped[key].append(value)print(dict(grouped))  # {'a': [1, 3], 'b': [2, 4]}# 自定义工厂函数def default_user():    return {"name""""age"0"scores": []}users = defaultdict(default_user)users["alice"]["name"= "Alice"  # 自动创建默认用户

1.3.2 Counter —— 计数器

from collections import Counter# 创建计数器words = ["apple""banana""apple""cherry""banana""apple"]= Counter(words)print(c)  # Counter({'apple': 3, 'banana': 2, 'cherry': 1})# 常用方法print(c.most_common(2))  # [('apple', 3), ('banana', 2)]print(c["apple"])        # 3print(c["orange"])       # 0(不报错)# 数学运算c1 = Counter(a=3, b=1)c2 = Counter(a=1, b=2)print(c1 + c2)  # Counter({'a': 4, 'b': 3})print(c1 - c2)  # Counter({'a': 2})print(c1 & c2)  # Counter({'a': 1, 'b': 1})  取最小print(c1 | c2)  # Counter({'a': 3, 'b': 2})  取最大# 更新计数c.update(["apple""apple"])  # apple计数+2c.subtract(["banana"])        # banana计数-1

1.3.3 OrderedDict —— 有序字典(Python 3.7+后普通dict已足够)

from collections import OrderedDict# Python 3.7+ 普通字典已经保持插入顺序# OrderedDict 的特殊功能:# 1. move_to_end - 移动键到末尾od = OrderedDict([("a"1), ("b"2), ("c"3)])od.move_to_end("a")  # a移到最后od.move_to_end("b", last=False)  # b移到最前# 2. popitem(last=False) - 弹出第一个first = od.popitem(last=False)# 3. 相等性比较考虑顺序od1 = OrderedDict([("a"1), ("b"2)])od2 = OrderedDict([("b"2), ("a"1)])print(od1 == od2)  # False(顺序不同)d1 = {"a"1"b"2}d2 = {"b"2"a"1}print(d1 == d2)  # True(普通字典不考虑顺序)

1.4 集合操作

1.4.1 集合基础

# 创建集合empty = set()  # 注意:{}创建的是空字典!nums = {12345}from_list = set([122333])  # {1, 2, 3}# 添加删除nums.add(6)nums.remove(3)      # KeyError if not existsnums.discard(10)    # 安全删除,不存在不报错item = nums.pop()   # 随机删除并返回nums.clear()# 集合推导式evens = {x for x in range(20if x % 2 == 0}

1.4.2 集合运算

= {12345}= {45678}# 交集print(a & b)              # {4, 5}print(a.intersection(b))  # {4, 5}# 并集print(a | b)         # {1, 2, 3, 4, 5, 6, 7, 8}print(a.union(b))    # {1, 2, 3, 4, 5, 6, 7, 8}# 差集print(a - b)              # {1, 2, 3}print(a.difference(b))    # {1, 2, 3}# 对称差集(异或)print(a ^ b)                       # {1, 2, 3, 6, 7, 8}print(a.symmetric_difference(b))   # {1, 2, 3, 6, 7, 8}# 子集/超集print(a.issubset(b))      # Falseprint(a.issuperset({12}))  # Trueprint(a.isdisjoint({67}))  # True(无交集)# 原地修改a.intersection_update(b)  # a = a & ba.update({910})         # a = a | {9, 10}

集合运算可视化:

    并集 (|)          交集 (&)         差集 (-)       对称差集 (^)   ┌─────┐          ┌─────┐          ┌─────┐         ┌─────┐   │ A B │          │  A  │          │ A   │         │ A B │   │  ◆ │          │  ◆ │          │     │         │     │   └─────┘          └─────┘          └─────┘         └─────┘   A ∪ B            A ∩ B            A - B           A △ B

二、底层原理深度解析

2.1 哈希表原理

核心概念: 哈希表(Hash Table)通过哈希函数将键映射到数组索引,实现O(1)查找。

哈希表结构示意:键 → 哈希函数 → 哈希值 → 取模 → 数组索引 → 存储位置示例:"apple"  →  hash()  →  123456789  →  % 8  →  5  →  存储到索引5"banana" →  hash()  →  987654321  →  % 8  →  1  →  存储到索引1

Python字典的内存布局:

┌─────────────────────────────────────────┐│  字典对象头部                            ││  - 引用计数、类型指针                     ││  - 条目数(used)                        ││  - 容量(capacity)                      │├─────────────────────────────────────────┤│  哈希表(索引数组)                       ││  ┌────┬────┬────┬────┬────┬────┬────┐   ││  │ -1 │  1 │ -1 │  0 │ -1 │ -1 │  2 │   ││  └────┴────┴────┴────┴────┴────┴────┘   ││   0    1    2    3    4    5    6       ││  (-1表示空,其他数字是条目数组索引)      │├─────────────────────────────────────────┤│  条目数组(存储键值对)                   ││  ┌─────────┬─────────┬─────────┐        ││  │ hash:   │ hash:   │ hash:   │        ││  │ key:    │ key:    │ key:    │        ││  │ value:  │ value:  │ value:  │        ││  │ idx: 0  │ idx: 1  │ idx: 2  │        ││  └─────────┴─────────┴─────────┘        │└─────────────────────────────────────────┘

2.2 哈希冲突与解决

哈希冲突: 不同键产生相同哈希值(或相同索引)。

Python的解决方案——开放寻址法:

# 探测序列(伪代码)def find_slot(key):    hash_val = hash(key)    idx = hash_val % capacity    while table[idx] is not empty:        if table[idx].key == key:            return idx  # 找到        # 冲突!探测下一个位置        idx = (idx * 5 + 1% capacity  # 二次探测变体    return idx  # 空槽位

冲突处理可视化:

初始状态:索引: 0   1   2   3   4   5   6   7     []  []  []  []  []  []  []  []插入"a"(hash=5):索引: 0   1   2   3   4   5   6   7     []  []  []  []  [] [a]  []  []插入"b"(hash=5,冲突!):探测序列:5→6索引: 0   1   2   3   4   5   6   7     []  []  []  []  [] [a] [b]  []插入"c"(hash=6,冲突!):探测序列:6→7索引: 0   1   2   3   4   5   6   7     []  []  []  []  [] [a] [b] [c]

2.3 Python 3.7+ 字典有序性保证

历史演进:

Python版本
实现方式
有序性
< 3.6
稀疏哈希表
无序
3.6
紧凑字典(实现细节)
有序(不保证)
>= 3.7
紧凑字典(语言特性)
有序(保证)

紧凑字典实现:

传统字典(稀疏):索引数组:[空, 条目2, 空, 条目0, 空, 空, 条目1, 空]条目数组:分散存储紧凑字典(Python 3.6+):索引数组:[空, 2, 空, 0, 空, 空, 1, 空]  (指向条目数组索引)条目数组:[条目0, 条目1, 条目2]  (按插入顺序紧密排列)优势:1. 更少的内存占用(条目数组连续)2. 缓存友好(顺序遍历更快)3. 自然保持插入顺序

2.4 字典查找O(1)底层证明

理论分析:

假设:- 哈希函数分布均匀- 负载因子 α = n/m ≤ 2/3(Python默认)- 使用开放寻址法查找时间 = 计算哈希 + 探测次数成功查找的平均探测次数:- 线性探测:≈ 1/2 * (1 + 1/(1-α))- 二次探测:≈ -ln(1-α)/α- Python的变体:接近1次当 α = 2/3 时:- 平均探测次数 < 2- 时间复杂度 ≈ O(1)

实际测试:

import timeimport randomdef benchmark_lookup():    sizes = [1000100001000001000000]    print("字典查找性能测试")    print("=" * 50)    print(f"{'大小':<15}{'总时间(ms)':<15}{'单次(ns)':<15}")    print("-" * 50)    for size in sizes:        # 创建字典        d = {i: f"value_{i}" for i in range(size)}        # 随机查找        keys = list(d.keys())        random.shuffle(keys)        # 计时        start = time.perf_counter()        for key in keys:            _ = d[key]        elapsed = (time.perf_counter() - start) * 1000        per_op = (elapsed * 1000000/ size  # 纳秒        print(f"{size:<15}{elapsed:<15.3f}{per_op:<15.1f}")benchmark_lookup()# 典型输出(证明O(1)):# 大小            总时间(ms)      单次(ns)# 1000            0.234           234.0# 10000           2.156           215.6# 100000          21.890          218.9# 1000000         234.567         234.6# 时间随大小线性增长,单次操作基本恒定

2.5 扩容机制

# Python字典扩容策略:# - 初始容量:8# - 扩容时机:当 used > 2/3 * capacity# - 扩容倍数:约4倍(小字典)或2倍(大字典)import sysdef show_dict_growth():    d = {}    for i in range(100):        d[i] = i        if i in [0510214285]:            print(f"元素数: {len(d):3}, 内存: {sys.getsizeof(d):4} bytes")show_dict_growth()# 输出示例:# 元素数:   1, 内存:  232 bytes# 元素数:   6, 内存:  360 bytes# 元素数:  11, 内存:  640 bytes# 元素数:  22, 内存: 1176 bytes# 元素数:  43, 内存: 2504 bytes# 元素数:  86, 内存: 5208 bytes

三、实战项目

3.1 项目一:词频统计TOP-N

from collections import Counterimport refrom typing import List, Tupleimport heapqclass WordFrequencyAnalyzer:    """词频分析器 - 支持多种统计方式"""    def __init__(self, text: str = ""):        self.text = text        self.words = []        self.counter = None    def tokenize(self, text: str = None-> List[str]:        """分词(简化版)"""        if text is None:            text = self.text        # 转小写,提取单词        text = text.lower()        # 匹配中文字符或英文单词        words = re.findall(r'[\u4e00-\u9fff]|[a-z]+', text)        # 过滤停用词(简化版)        stopwords = {'the''a''an''is''are''was''were'                     '的''了''在''是''和''有'}        return [w for w in words if w not in stopwords and len(w) > 1]    def analyze(self, text: str = None-> Counter:        """分析词频"""        self.words = self.tokenize(text)        self.counter = Counter(self.words)        return self.counter    def top_n(self, n: int = 10-> List[Tuple[strint]]:        """获取TOP N"""        if self.counter is None:            self.analyze()        return self.counter.most_common(n)    def top_n_heap(self, n: int = 10-> List[Tuple[strint]]:        """使用堆获取TOP N(适合大数据)"""        if self.counter is None:            self.analyze()        # nlargest比排序整个Counter更高效        return heapq.nlargest(n, self.counter.items(), key=lambda x: x[1])    def frequency_distribution(self) -> dict:        """频率分布统计"""        if self.counter is None:            self.analyze()        dist = {}        for word, count in self.counter.items():            dist[count] = dist.get(count, 0+ 1        return {            "total_words"len(self.words),            "unique_words"len(self.counter),            "frequency_dist"sorted(dist.items(), reverse=True)        }    def find_phrases(self, n: int = 2, min_freq: int = 2-> List[Tuple[Tuple[str, ...], int]]:        """查找高频短语(n-gram)"""        if not self.words:            self.words = self.tokenize()        phrases = []        for i in range(len(self.words) - n + 1):            phrase = tuple(self.words[i:i+n])            phrases.append(phrase)        phrase_counter = Counter(phrases)        return [(p, c) for p, c in phrase_counter.most_common() if c >= min_freq]    def generate_report(self, top_n: int = 20-> str:        """生成分析报告"""        if self.counter is None:            self.analyze()        dist = self.frequency_distribution()        top_words = self.top_n(top_n)        report = f"""╔════════════════════════════════════════════════╗║           词 频 统 计 报 告                     ║╚════════════════════════════════════════════════╝【基本信息】  总词数: {dist['total_words']}  不同词汇数: {dist['unique_words']}  词汇丰富度: {dist['unique_words']/dist['total_words']:.2%}【高频词汇 TOP {top_n}"""        max_count = top_words[0][1if top_words else 1        for rank, (word, count) in enumerate(top_words, 1):            bar_len = int(30 * count / max_count)            bar = "█" * bar_len            report += f"  {rank:2}{word:15}{count:4}{bar}\n"        # 频率分布        report += "\n【频率分布】\n"        for freq, count in dist['frequency_dist'][:10]:            report += f"  出现{freq:3}次的词有 {count:4} 个\n"        return report# 使用示例text = """Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。Python源代码遵循GPL协议。Python语法简洁清晰,特色之一是强制用空白符缩进。Python具有丰富的标准库和第三方库,广泛应用于Web开发、数据分析、人工智能等领域。"""analyzer = WordFrequencyAnalyzer(text)print(analyzer.generate_report(15))# 查找高频短语print("\n【高频短语(2-gram)】")for phrase, count in analyzer.find_phrases(n=2, min_freq=1):    print(f"  {' '.join(phrase)}{count}")

3.2 项目二:电话簿系统

from typing import Dict, List, Optional, Setfrom dataclasses import dataclass, fieldfrom collections import defaultdict@dataclassclass Contact:    """联系人"""    name: str    phone: str    email: str = ""    groups: Set[str= field(default_factory=set)    notes: str = ""    def __hash__(self):        return hash(self.phone)    def __eq__(self, other):        if isinstance(other, Contact):            return self.phone == other.phone        return Falseclass PhoneBook:    """电话簿系统 - 支持多索引查询"""    def __init__(self):        # 主存储:手机号 -> 联系人        self._by_phone: Dict[str, Contact] = {}        # 辅助索引        self._by_name: Dict[str, Set[str]] = defaultdict(set)  # 姓名 -> 手机号集合        self._by_group: Dict[str, Set[str]] = defaultdict(set)  # 分组 -> 手机号集合        self._by_email: Dict[strstr= {}  # 邮箱 -> 手机号    def add(self, contact: Contact) -> bool:        """添加联系人"""        if contact.phone in self._by_phone:            print(f"手机号 {contact.phone} 已存在")            return False        # 主存储        self._by_phone[contact.phone] = contact        # 更新索引        self._by_name[contact.name].add(contact.phone)        for group in contact.groups:            self._by_group[group].add(contact.phone)        if contact.email:            self._by_email[contact.email] = contact.phone        return True    def remove(self, phone: str-> bool:        """删除联系人"""        if phone not in self._by_phone:            return False        contact = self._by_phone[phone]        # 清理索引        self._by_name[contact.name].discard(phone)        if not self._by_name[contact.name]:            del self._by_name[contact.name]        for group in contact.groups:            self._by_group[group].discard(phone)            if not self._by_group[group]:                del self._by_group[group]        if contact.email:            del self._by_email[contact.email]        # 主存储删除        del self._by_phone[phone]        return True    def update(self, phone: str**kwargs) -> bool:        """更新联系人"""        if phone not in self._by_phone:            return False        contact = self._by_phone[phone]        # 清理旧索引        self._by_name[contact.name].discard(phone)        for group in contact.groups:            self._by_group[group].discard(phone)        if contact.email:            del self._by_email[contact.email]        # 更新字段        for key, value in kwargs.items():            if hasattr(contact, key):                setattr(contact, key, value)        # 重建索引        self._by_name[contact.name].add(phone)        for group in contact.groups:            self._by_group[group].add(phone)        if contact.email:            self._by_email[contact.email] = phone        return True    def find_by_phone(self, phone: str-> Optional[Contact]:        """按手机号查找"""        return self._by_phone.get(phone)    def find_by_name(self, name: str-> List[Contact]:        """按姓名查找"""        phones = self._by_name.get(name, set())        return [self._by_phone[p] for p in phones]    def find_by_group(self, group: str-> List[Contact]:        """按分组查找"""        phones = self._by_group.get(group, set())        return [self._by_phone[p] for p in phones]    def find_by_email(self, email: str-> Optional[Contact]:        """按邮箱查找"""        phone = self._by_email.get(email)        return self._by_phone.get(phone) if phone else None    def search(self, keyword: str-> List[Contact]:        """模糊搜索"""        results = set()        keyword = keyword.lower()        for contact in self._by_phone.values():            if (keyword in contact.name.lower() or                keyword in contact.phone or                keyword in contact.email.lower() or                keyword in contact.notes.lower()):                results.add(contact)        return list(results)    def add_to_group(self, phone: str, group: str-> bool:        """添加联系人到分组"""        if phone not in self._by_phone:            return False        contact = self._by_phone[phone]        contact.groups.add(group)        self._by_group[group].add(phone)        return True    def get_groups(self) -> List[str]:        """获取所有分组"""        return list(self._by_group.keys())    def get_stats(self) -> dict:        """获取统计信息"""        return {            "total_contacts"len(self._by_phone),            "unique_names"len(self._by_name),            "groups"len(self._by_group),            "with_email"len(self._by_email)        }    def export(self) -> List[dict]:        """导出所有联系人"""        return [            {                "name": c.name,                "phone": c.phone,                "email": c.email,                "groups"list(c.groups),                "notes": c.notes            }            for c in self._by_phone.values()        ]    def print_all(self):        """打印所有联系人"""        print("\n" + "=" * 80)        print("电话簿".center(80))        print("=" * 80)        for contact in sorted(self._by_phone.values(), key=lambda c: c.name):            print(f"\n姓名: {contact.name}")            print(f"  电话: {contact.phone}")            if contact.email:                print(f"  邮箱: {contact.email}")            if contact.groups:                print(f"  分组: {', '.join(contact.groups)}")            if contact.notes:                print(f"  备注: {contact.notes}")# 使用示例def demo():    book = PhoneBook()    # 添加联系人    contacts = [        Contact("张三""13800138000""zhangsan@example.com", {"同事""好友"}),        Contact("李四""13800138001""lisi@example.com", {"同事"}),        Contact("王五""13800138002""wangwu@example.com", {"好友"}),        Contact("赵六""13800138003", groups={"家人"}),    ]    for c in contacts:        book.add(c)    # 查询演示    print("\n按姓名查找'张三':")    for c in book.find_by_name("张三"):        print(f"  {c}")    print("\n按分组查找'同事':")    for c in book.find_by_group("同事"):        print(f"  {c.name}{c.phone}")    print("\n模糊搜索'138':")    for c in book.search("138"):        print(f"  {c.name}{c.phone}")    # 统计    print("\n统计信息:")    print(book.get_stats())    # 打印全部    book.print_all()if __name__ == "__main__":    demo()

四、常见陷阱与解决方案

4.1 可变对象作为字典键

# 陷阱:使用可变对象作为键# d = {[1, 2]: "value"}  # TypeError: unhashable type: 'list'# 原因:列表是可变的,哈希值会改变,破坏哈希表不变性# 解决方案1:转换为元组= {(12): "value"}# 解决方案2:使用frozenset= frozenset([123])= {s: "value"}# 解决方案3:自定义类实现__hash__class Point:    def __init__(self, x, y):        self.x = x        self.y = y    def __hash__(self):        return hash((self.x, self.y))    def __eq__(self, other):        return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)= {Point(12): "A"}

4.2 字典遍历时修改

# 陷阱:遍历时修改字典# d = {"a": 1, "b": 2, "c": 3}# for k in d:#     if d[k] < 2:#         del d[k]  # RuntimeError: dictionary changed size during iteration# 正确做法1:遍历键的副本for k in list(d.keys()):    if d[k] < 2:        del d[k]# 正确做法2:字典推导式= {k: v for k, v in d.items() if v >= 2}# 正确做法3:标记后删除to_delete = [k for k, v in d.items() if v < 2]for k in to_delete:    del d[k]

4.3 defaultdict的默认工厂陷阱

from collections import defaultdict# 陷阱:默认工厂返回可变对象的同一个引用= defaultdict(list)d["a"].append(1)print(d["b"])  # [] - 新的空列表# 但如果是自定义对象:class Container:    def __init__(self):        self.items = []= defaultdict(Container)c1 = d["a"]c2 = d["a"]print(c1 is c2)  # True - 同一个对象!# 正确做法:使用lambda每次创建新对象= defaultdict(lambda: Container())c1 = d["a"]c2 = d["a"]print(c1 is c2)  # True - 还是同一个(因为"a"已存在)c3 = d["b"]print(c1 is c3)  # False - 不同key不同对象

4.4 集合运算的副作用

= {123}= {345}# 陷阱:& 和 | 返回新集合,但 &= 和 |= 原地修改original_id = id(a)# 返回新集合result = a & bprint(id(result) == original_id)  # False# 原地修改&= bprint(id(a) == original_id)  # True# 注意:使用赋值会改变变量指向= {123}= a & b  # 新集合,原集合可能被GC

4.5 哈希一致性陷阱

# 陷阱:修改对象后哈希值改变class BadKey:    def __init__(self, value):        self.value = value    def __hash__(self):        return hash(self.value)    def __eq__(self, other):        return isinstance(other, BadKey) and self.value == other.valuekey = BadKey(1)= {key: "value"}print(d[key])  # "value"key.value = 2  # 修改了!# print(d[key])  # KeyError! 哈希值变了,找不到# 正确做法:使用不可变对象或确保对象不可变class GoodKey:    def __init__(self, value):        self._value = value  # 私有,不暴露修改接口    @property    def value(self):        return self._value    def __hash__(self):        return hash(self._value)    def __eq__(self, other):        return isinstance(other, GoodKey) and self._value == other._value

五、本章小结

核心知识点回顾

主题
要点
字典基础
创建、访问、修改、删除、遍历
字典方法
get/setdefault/update/pop/popitem
高级类型
defaultdict、Counter、OrderedDict
集合操作
交并差、子集判断、集合推导
哈希原理
哈希函数、冲突解决、开放寻址
有序性
Python 3.7+字典保持插入顺序
性能
O(1)查找、扩容策略、负载因子

数据结构选择指南

需要键值映射 → 字典(dict)  ├─ 需要自动默认值 → defaultdict  ├─ 需要计数 → Counter  └─ 需要保持顺序 → dict (3.7+) 或 OrderedDict需要去重 → 集合(set)/frozenset  ├─ 需要可哈希 → frozenset  └─ 集合运算 → set需要有序序列 → 列表(list)/元组(tuple)查找效率对比(n个元素):  列表查找: O(n)  字典/集合查找: O(1)

最佳实践清单

  •  优先使用字典推导式创建字典
  •  使用get()进行安全访问
  •  使用setdefault或defaultdict处理缺失键
  •  使用Counter进行词频统计
  •  使用集合进行成员判断和去重
  •  不要在遍历时修改字典
  •  不要用可变对象作为字典键
  •  理解哈希一致性要求

六、课后练习

基础练习

  1. 两数之和:给定数组和目标值,找出和为目标值的两个数的索引

    two_sum([271115], 9)  # [0, 1] 因为 2+7=9

    要求:使用字典实现O(n)时间复杂度

  2. 字符异位词:判断两个字符串是否为异位词(字符相同,顺序不同)

    is_anagram("listen""silent")  # True

    要求:使用Counter实现

  3. 最长连续序列:找出未排序数组中最长连续序列长度

    longest_consecutive([1004200132])  # 4 ([1,2,3,4])

    要求:使用集合实现O(n)复杂度

进阶练习

  1. LRU缓存:实现LRU(最近最少使用)缓存

    cache = LRUCache(2)cache.put(11)cache.put(22)cache.get(1)    # 返回 1cache.put(33# 淘汰 key 2cache.get(2)    # 返回 -1 (未找到)
  2. 一致性哈希:实现简单的一致性哈希环

    • 支持添加/删除节点
    • 支持数据分布查询
  3. 倒排索引:为文档集合构建倒排索引

    • 支持添加文档
    • 支持关键词搜索
    • 返回包含关键词的文档列表

挑战练习

  1. 布隆过滤器:实现布隆过滤器

    • 支持添加元素
    • 支持查询(可能误判,不会漏判)
  2. 跳表:实现跳表(Skip List)

    • 实现插入、删除、查找
    • 与字典性能对比

参考资源

  • Python字典实现源码
  • Python集合实现源码
  • 哈希表维基百科
  • Python 3.6新字典实现

本文是《Python全栈修炼之路》系列第5篇,持续更新中,欢迎关注专栏获取更多内容!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 05:24:12 HTTP/2.0 GET : https://f.mffb.com.cn/a/496795.html
  2. 运行时间 : 0.109759s [ 吞吐率:9.11req/s ] 内存消耗:4,752.22kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=9e9693a70c17981ec0e9aa8689a9f5cc
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000456s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000808s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000342s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000264s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000514s ]
  6. SELECT * FROM `set` [ RunTime:0.000283s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000590s ]
  8. SELECT * FROM `article` WHERE `id` = 496795 LIMIT 1 [ RunTime:0.000794s ]
  9. UPDATE `article` SET `lasttime` = 1783027452 WHERE `id` = 496795 [ RunTime:0.024270s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000381s ]
  11. SELECT * FROM `article` WHERE `id` < 496795 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000639s ]
  12. SELECT * FROM `article` WHERE `id` > 496795 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.006386s ]
  13. SELECT * FROM `article` WHERE `id` < 496795 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001531s ]
  14. SELECT * FROM `article` WHERE `id` < 496795 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000815s ]
  15. SELECT * FROM `article` WHERE `id` < 496795 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000778s ]
0.111323s