python2和python3的区别
print语句被python3废弃,只能使用print函数
Python3中字符串是Unicode (utf-8)编码,支持中文做标识符。
python2中是ASCII编码,需要更改字符集才能正常支持中文,所以在.py文件中会看到#-- coding: UTF-8 --
异常处理 Python2中try:...except Exception, e:...,在Python3中改为了try:...except Exception as e:...
Python3中不再使用xrange方法,只有range方法。
range在Python2中返回列表,而在Python3中返回range可迭代对象。
在Python2中有两个不等运算符!=和<>,在Python3中去掉了<>,只有!=符号表示不等
在Python2中双反引号`可以替代repr函数,在Python3中去掉了双反引号的表是方法,只能用repr`方法。
StringIO模块现在被合并到新的io模组内。new, md5, gopherlib等模块被删除。
httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。
取消了exec语句,只剩下exec()函数。
在Python2中long是比int取值范围更大的整数,Python3中取消了long类型,int的取值范围扩大到之前的long类型范围。
列表推导 不再支持[n for n in a,b]语法,改为[n for n in (a,b)]或[n for n in [a,b]]
python 2 中通过input输入的类型是int,只有通过raw_input()输入的类型才是str。
python 3中通过input输入的类型都是str,去掉了row_input()方法。
python3.6中dict有序
有序是指遍历时的输出顺序与输入顺序相同
关于哈希表
- 散列表概念 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
- 哈希函数 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。 (相关:是不是可以这样理解,数组可以通过下标进行访问,时间复杂度是O(1),对于不连续存储的数据结构,如果知道下标也可以直接进行访问,所以可以通过哈希函数将key映射成数组下标,进行访问)
- 冲突 不同的key经过hash函数运行后得到相同的值,产生冲突;
- 冲突解决方式
- 开放寻址:线性探测、二次探测、伪随机数序列(python的dict解决冲突用的这个,具体的策略没有看太明白)
- 再哈希法:将哈希值再哈希,然后存储;
- 链地址法:hash过后值相同的存储在链表里;
- 公共溢出区
python实现dict无序到有序:
- 原先的内存布局entries为哈希表,表中直接存储PyDictKeyEntry(hash、key、value),也就是说当当前位置为空的时候存的是(0, null, null)浪费了大量内存;
- python3.6: indices充当哈希表,存储的entries的index,使用index去访问存有PyDictKeyEntry的数组
python3 dict性能优化
节省存储空间:将存储PyDictKeyEntry的稀疏数组更改为存储int的稀疏数组; 之前的dict_entry是稀疏表,经压缩后在密集表上循环,使用更少的内存; 调整大小更快,并且触及更少的内存。 目前,每一个散列/键/值条目在一个过程中被移动或复制调整。 在新的布局中,只有索引是更新。 大多数情况下,散列/键/值条目从不移动(除了偶尔交换填充删除留下的空洞)。
range和xrange区别
range返回的是一个包含所有元素的列表,xrange返回的是一个生成器,生成器是一个可迭代对象,在对生成器进行迭代时,元素是逐个被创建的。而列表需要根据列表长度而开辟出相应的内存空间用来遍历,一般来看,在对大序列进行迭代的时候,因为xrange的特性,所以它会比较节约内存。