python字典相关操作的复杂度_字典查找的时间复杂度-程序员宅基地

技术标签: python  Python  

最近对大量数据做处理时,耗时较大,后来通过改进用了字典,一定程度上提高了效率。
字典与列表的不同之处在于,可以通过键而不是位置来访问字典中的项。字典上的get item和set item操作是O(1)。另一个重要的字典操作是contains操作,即检查一个键是否在字典中也是O(1)。下图总结了所有字典操作的效率。该图中提供的效率是针对平均性能的。在一些罕见的情况下,contains、get item和set item操作可能会退化为O(n)性能。
在这里插入图片描述
字典相关操作的代码:

# dictionary 类似Map哈希表
d = {
    'cat': 'cute', 'dog': 'furry'}
print(d['cat'])
print('cat' in d)
d['fish'] = 'wet'
print(d['fish'])
# print(d['monkey'])  # KeyError: 'monkey' not a key of d
print(d.get('monkey', 'N/A'))
print(d.get('fish', 'N/A'))
del d['fish']
print(d.get('fish', 'N/A'))

d = {
    'person': 2, 'cat': 4, 'spider': 8}
for animal in d:
    legs = d[animal]
    print('A %s has %d legs' % (animal, legs))
    
d = {
    'person': 2, 'cat': 4, 'spider': 8}
for animal, legs in d.items():
    print('A %s has %d legs' % (animal, legs))
    
nums = [0, 1, 2, 3, 4]
even_num_to_square = {
    x: x ** 2 for x in nums if x % 2 == 0}
print(even_num_to_square)

使用python字典来进行查找的话速度非常快,是O(1)级别,因为是用hash实现的。
哈希表也叫散列表,可理解为借助哈希函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性,是存储 Key-Value 键值对的集合。参考文章:知乎:什么是哈希表?
存放记录的哈希表结构如图所示(数组下标index与[key,value]键值对):
在这里插入图片描述

关于哈希表的基本原理可简单理解为:当我们用字典当中的key去获取对应的value时,会将key转换为列表当中的index,通过index去准确快速地获取到value。这里面的关键在于哈希函数与冲突检测
key转化为index的函数就称为哈希函数,其中key既可以为数字,也可以为字符串,哈希函数通过计算模值或计算字符串哈希值得到对应的数组下标(存储地址)。可见,不需要遍历地址,而只通过一次计算即得到地址,从而方便取该地址存放的值,则在不冲突的理想情况下,时间复杂度为O(1)。总体来说,若设计好哈希函数减少冲突次数,则时间复杂度的平均性能为O(1)。
而在计算index的时候要注意冲突检测(例如多个key通过哈希函数后同时对应到同一index),这时候主要通过index与其存放的key进行处理(可参考如下代码)。根据冲突检测的处理方法可以将检测方法分为开放寻址法拉链法
我们可以通过如下数组模拟散列表的问题进行理解,该问题实现了加入元素与判断元素是否存在的功能。通过计算得到要查找的key所对应的数组的下标k,并进行冲突检测(若有冲突,则k++),从平均性能上来说,确实可以达到O(1)。这种冲突检测方法为开放寻址法,除此之外还有基于链表的拉链法。该问题中存放的是key,即仅存放不重复的元素,其实就类似于hashset。若加入value,每个数组位置存放一个键值对[key, value],其实就类似于hashtable,key通常用来冲突检测与快速查找,而value用于存储对应于key的值。而hashtable与dictionary是较为相近的,具体区别之后再具体调研。
数组模拟散列表问题链接如下:
AcWing 840. 模拟散列表
该问题C++代码:

#include <cstring>
#include <iostream>

using namespace std;
// N为模数,null为空位置的初始值
// N通常取大于范围的质数,取质数冲突的概率最小
const int N = 2e5 + 3, null = 0x3f3f3f3f;

int h[N];

int find(int x) // 哈希函数:通过key得到对应的数组下标索引值(k)
{
    
    int k = ((x % N) + N) % N; // key->index(k)
    while(h[k] != null && h[k] != x) // 冲突检测
    {
    
        k ++;
        if(k == N) k = 0;
    }
    return k; // 返回地址
}

int main()
{
    
    int n;
    scanf("%d", &n);
    
    // 数组初始化为无穷大,无穷大表示不存放值
    memset(h, 0x3f, sizeof h); 
      
    while(n --)
    {
    
        char op[2];
        int x;
        scanf("%s%d", op, &x);
        int k = find(x);
        if(*op == 'I') h[k] = x; // 插入元素
        else // 判断存在
        {
    
            if(h[k] != null) puts("Yes");
            else puts("No");
        }
    }
    
    return 0;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/whq___/article/details/116244384

智能推荐

SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)-程序员宅基地

文章浏览阅读96次。前言上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握。通过本篇可以了解我们平常所写的T-SQL语句,在SQL Server数据库系统中是如何分解执行的,数据结果如何通过各个运算符组织形成的。技术准备基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析...

渗透测试实例:Metasploitable3靶机-程序员宅基地

文章浏览阅读3.8k次,点赞5次,收藏26次。实验环境:Kali虚拟机一台、4G运行,Metasploitable3靶机一台,IP地址192.168.22.20实验目的:对Metasploitable3靶机进行渗透测试实验步骤:(一),对靶机进行扫描1,使用Neuss对靶机进行扫描_metasploitable3

C语言bfs算法自动走贪吃蛇,智能寻路贪吃蛇系列之 初级BFS寻路算法-程序员宅基地

文章浏览阅读240次。//Bfs.cpp#include "stdafx.h"#include "Bfs.h"int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};void Bfs::InitBfs(bool **chess,XY size){m_size=size;m_chess=new bool *[m_size.x];m_visit=new bool *[m_size.x];m_pa..._bfs贪吃蛇

技术讨论:我心中TOP1的编程语言_内存安全的编程语言-程序员宅基地

文章浏览阅读6.6k次,点赞13次,收藏14次。编程语言(programming language)是一种计算机和人之间交流的形式。它是一种为了完成计算机任务而编写的特定语言。编程语言包括指令、变量、函数、条件语句、循环语句等等。程序员使用编程语言来告诉计算机执行任务,例如打开文件、执行数学运算、连接数据库等等。不同的编程语言适用于不同的应用领域,例如Java和Python在Web开发、机器学习、数据分析等领域应用广泛,而C++在操作系统、游戏开发等领域应用较多。【百度百科释义】_内存安全的编程语言

mysql 实数型变量定义,PL/pgSQL从入门到放弃(2)-变量定义与数据类型-程序员宅基地

文章浏览阅读256次。本文由 @小刘先森 原创,转载请注明出处。使用PL/pgSQL也有比较久的时间了,写几篇从入门开始学习的文章,方便小伙伴们学习。PL/pgSQL从入门到放弃(1)-入门PL/pgSQL从入门到放弃(2)-变量定义与数据类型PL/pgSQL从入门到放弃(3)-函数PL/pgSQL从入门到放弃(4)-控制结构PL/pgSQL从入门到放弃(5)-游标声明变量上一篇介绍到,PL/pgSQL是块结构的语言。..._plsql实数

warning C4251-程序员宅基地

文章浏览阅读115次。c++ - Warning C4251 when building a DLL that exports a class containing an ATL::CString member - Stack Overflow_warning c4251

随便推点

skywalking 自定义插件_skywalking自定义插件-程序员宅基地

文章浏览阅读3.1k次。环境基于skywalking-java开发,就是skywalking的java agent,这次在基础上开发一个自定义的插件。流程演示首先新建一个model修改pom文件<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sc._skywalking自定义插件

UTM投影的选择(地区->投影带)_utm投影选择-程序员宅基地

文章浏览阅读1.4w次,点赞10次,收藏53次。如果要在ArcMAP中启用shape.area和shape.length计算(几何计算),需要设置投影坐标,WGS-1984地理坐标系一般都设置为UTM投影,涉及不同经纬度不同分带选择,下面详细介绍一下UTM投影。UTM 投影(Universal Transverse Mercator,通用横轴墨卡托投影)是由美国军方在1947提出的,美国本土采用Clarke 1866椭..._utm投影选择

自定义数据库连接池实现方式 MySQL_连接到自定义区域的mysql-程序员宅基地

文章浏览阅读1k次。应用程序直接获取数据库连接缺点用户每次请求都会建立一次数据库连接,并且数据库创建连接会消耗相对大的资源和时间。如果针对于个别的工具或者是大量的代码测试甚至系统运行,对数据库操作次数频繁,极大的占用数据库资源,有可能会发生宕机或者内存溢出的现象。而在大多的项目中,常常用到阿里巴巴开源的数据库连接池框架,准确来说它不仅仅包括数据库连接池,原因其实很简单,在Spring框架的配置文件中仅仅一..._连接到自定义区域的mysql

java 虚拟机最佳实践_深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)-程序员宅基地

文章浏览阅读43次。第1版两年内印刷近10次,4家网上书店的评论近4?000条,98%以上的评论全部为5星级的好评,是整个Java图书领域公认的经典著作和超级畅销书,繁体版在台湾也十分受欢迎。第2版在第1版的基础上做了很大的改进:根据最新的JDK1.7对全书内容进行了全面的升级和补充;增加了大量处理各种常见JVM问题的技巧和最佳实践;增加了若干与生产环境相结合的实战案例;对第1版中的错误和不足之处的修正等等。第2版不...

程序员进阶篇:简单聊聊mysql的脏读、不可重复读-程序员宅基地

文章浏览阅读905次,点赞18次,收藏13次。脏读,就是读到了其他会话还没有提交的修改。下面用例子说明:可以看到,会话 2 修改了 id 为 222 的用户,在还没提交或回滚事务之前,会话 1 就读到了这些改动。脏读的本质就是,还没结束的写操作被读操作分割了。所以,为了解决脏读,就必须让写操作不可被读操作分割(当然,也不能被其他写操作分割),即保证所谓的原子性。不可重复读,就是在同一个事务中,多次读相同的记录但读到了不同的结果。

eclipse javaee版本配置tomcat并向tomcat发布工程 ._eclipse javaee 编译 发布-程序员宅基地

文章浏览阅读3.9k次。1.下载最新的eclipse javaee版本,下载地址为:http://www.eclipse.org/downloads/,这里注意一定要选择javaee版本,2.Tomcat下载,链接为:http://tomcat.apache.org/3.下载eclipse tomcat插件,下载地址为:http://download.csdn.net/detail/longsheng_eclipse javaee 编译 发布

推荐文章

热门文章

相关标签