哈希表的实现 何为哈希表 简单来说,哈希表是一种存储结构,它存储的数据是 key:value 类型的。通过空间换时间的方法来加快查询速度,具体思想是如下: 使用一个较大的一维数组存储value,这个数组为Array 实现一个哈希函数,使得hash(key)的值在上一步的一维数组下标范围内 如此,对于任意的key:value,使用hash(key),之后就可以知道value在数组中存储的下标,存取速度快过线性查找Array[hash(key)] 哈希表的注意要点 哈希函数的选取 由于我们期望,两个不同的key,hash(key)之后的结果尽量不相同,这样才能使得哈希表存储空间的利用率提高,另一点,哈希表的空间换时间的主要原因就是他使用了哈希函数来确定value在数组中的下标而非普通的线性查找。那么,基于以上两点,哈希函数的选取就有以下条件: hash函数运行速度不能过慢 对于不同的key(即便两个key只是字母顺序不一致),哈希函数须尽量保证hash(key)的值不一致 处理哈希碰撞 由于是无论k 继续阅读 >>


李余通 18/10/09 20:17:14
Ajax对于表单提交来说,是一个很好的工具,他提供了异步提交的效果,这使得用户提交表单时不需要刷新页面就可获知提交成功与否,但一直以来,网上的示例大都是JQuery上传的教程,原生Ajax似乎并不受大家热爱,更别提原生Ajax上传图片的教程了,本篇将为你讲述JavaScript中使用FormData上传文件的教程 FormData FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。比起早先的Ajax,发送FormData的Ajax不仅可以发送图片,更好的一点是我们无需设置RequestHeader,也无需担心自己粗心写错xhr.send()中的参数。 用法 我们可以使用表单来构造一个FormData对象,也可以创建一个空的FormData对象,之后手动添加一些数据进去。 使用表单构造FormData对象。 做法很简单,使用getElementById()或querySelector()这类选择器获取表单对象,将其传入FormData的构造方 继续阅读 >>


李余通 18/06/20 20:29:20
ECharts 官网的内容已经非常详细了,我就不再赘述。下面写写我使用时遇到的问题: 饼状图无法添加标题: 实际上也是设置title字段,只是这个字段是在option下而非series下(刚开始大意了) 饼状图添加内容百分数显示: tooltip : { trigger: 'item', formatter: "{a} <br/>{b} : {c} ({d}%)" }, 作者:baidu_35085676 发表于 2018/06/11 10:42:59 原文链接 https://blog.csdn.net/baidu_35085676/article/details/80648643 阅读:348 继续阅读 >>


李余通 18/06/11 10:42:59
mako模板算是Python里面比较出色的一个模板了,它宣称有比Jinja2更快的解析速度已经更多的语法支持,本篇博客对它的使用做一个小结。 安装 使用pip可以方便的安装 # 无需root权限,安装到用户目录下 pip install mako --user #python2 pip3 install mako --user #python3 使用 Template 通过from mako.template import Template引入mako模板,最基础的用法是这样: from mako.template import Template t = Template("Hello,${name}") print(t.render(name = 'world')) ==>Hello,world Template函数还有一些常用的参数: filename:指定从文件中加载模板。最好用相对路径,否则缓存文件会包含在很长的路径下。 module_directory: 继续阅读 >>


李余通 18/06/03 22:01:58
最近得知凤凰os,给自己平板也装了个这个系统,感觉蛮不错的,系统的tty1有root权限,但是安装的apk却没有root权限,直接安装super su提示su文件被占用,原因是系统自带的su文件动手脚了,只能给tty1用,我们的解决方法就是下载官方的su文件。遂寻找解决办法,参考网络,方法如下: 1. 去官网下载zip包。解压到本地。假定解压到了/sdcard/Download/su/ 2. 按alt+F1进入系统终端 3. cd /system/xbin 4. mv su su.bak 5. cp /sdcard/Download/su/x86/su.pie su 如果是x64架构就复制x64目录下的 6. su --install 7. su --daemon 8. alt+F7切换会GUI,在su/common/,目录中安装supersu.apk 9. 打开supersu.apk点击确定更新su文件 10. 选择常规 11. 重启系统 获取root权限教程完毕 继续阅读 >>


李余通 18/05/08 10:55:55
关于Python的web application,可以参考PEP-3333。另外,我还找到了一篇翻译,英文有困难的童鞋可以点这里。 WSGI Python Web Server Gateway Interface,翻译过来时Python web服务器网关接口,实际上就是一种协议,我们的应用(Django,Flask)实现了WSGI,就可以配合实现了WSGI(uWSGI,gunicorn)的服务器工作了。 以下是他们的结构图。 下面详述两种模式: 两级结构 在这种结构里,uWSGI作为服务器,它用到了HTTP协议以及wsgi协议,flask应用作为application,实现了wsgi协议。当有客户端发来请求,uWSGI接受请求,调用flask app得到相应,之后相应给客户端。 这里说一点,通常来说,Flask等web框架会自己附带一个wsgi服务器(这就是flask应用可以直接启动的原因),但是这只是在开发阶段用到的,在生产环境是不够用的,所以用到了uwsgi这个性能高的ws 继续阅读 >>


李余通 18/05/04 13:58:49
本文是我看了http://python.jobbole.com/88291/后加上自己的一些感想所创 我们都知道,IO比CPU慢很多个数量级,而传统的IO,是阻塞型的,CPU花在等待IO上的时间很多,那么想要提高并发量,选择解决CPU在等待IO上花费的大量时间是一个比较好的出路。 先来看一个阻塞型IO的例子。 同步阻塞下载程序 该脚本的功能是下载10个网页。 import socket urls = ['/'+str(i) for i in range(10)] host = 'www.baidu.com' def fn(url): sock = socket.socket() sock.connect((host,80)) # 这里会阻塞直到发送成功 #send不会阻塞 sock.send(('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' % (url,host)).encode('utf-8')) respon 继续阅读 >>


李余通 18/04/24 23:53:57
Python中一共有三种推导式,做一个简述。 推导式的结构 开始符号 处理结果 迭代对象 过滤条件 结束符号 列表推导式 读取输入的内容并转成整数。 [int(x) for x in sys.stdin.readline().split() if x != '\n'] 开始符号:[ 结束符号:] 处理结果:int(x) 迭代对象:for x in sys.stdin.readline().split() 过滤条件:if x != '\n' #实际上这句话可以不要 会生成一个类似[1,2,3,4]的列表 生成器表达式 这个和列表推导式很类似,只是开始符号和结束符号变成了()。 生成器的好处是惰性计算,不会一下子占用太多内存。 集合推导式 这个和列表推导式很类似,只是开始符号和结束符号变成了{}。 {x**2 for x in [1,2,3,4,1,2,3] if x != 1} ==>{16, 9, 4} 字典推导式 符号:{} 处理结果k:v #e 继续阅读 >>


李余通 18/04/22 10:23:44
这个需求比较奇怪,要求实现Sum和MagaSum函数,实现以下功能 Sum(1) =>1 Sum(1,2,3) =>6 MegaSum(1)() =>1 MegaSum(1)(2)(3)() =>6 实际上Sum就是Python自建的sum函数,它支持变参,变参怎么实现,自然是*args,所以很容易写出雏形: Sum def Sum(*args): count = 0 for i in args: count+=i return count 第二个函数就有点皮了,它要求有参数的时候,返回的值是一个函数的引用,无参数的时候,返回的是结果。 要实现可以有或无参数,那么首想到的是Python的默认参数。我们可以默认参数值是None,当主动传入参数时,返回一个函数的引用,否则,返回结果。这里用到了Python可变类型作为函数参数时的一些特性。代码如下: def Sum(*args): s = 0 for i i 继续阅读 >>


李余通 18/04/15 20:50:14
很多时候,我们需要对已经实现的功能进行扩展,即增加新的功能,那么,最容易想到的就是就是对原有功能进行修改,这个时候免不了要修改原始代码,但面向对象编程的一个思想是开放封闭原则,即: 开放:对扩展开发 封闭:对已实现的功能模块 已实现的功能可以被扩展,不能被修改 需求来了 现在有一个函数 def do(msg): print("do %s..." % msg) 现在要求执行do之前打印一句before do...,执行完之后打印一句end do... 很容易想到这样的做法: def other_do(msg): print('before do...') do(msg) print('end do...') 功能达到了,但是有一个问题,我实际调用的函数已经不是do(msg),而是other_do(msg)了,那么有没有什么别的方法呢? 答案是装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的 继续阅读 >>


李余通 18/04/10 18:20:13