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有序

有序是指遍历时的输出顺序与输入顺序相同

关于哈希表

  1. 散列表概念 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
  2. 哈希函数 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。 (相关:是不是可以这样理解,数组可以通过下标进行访问,时间复杂度是O(1),对于不连续存储的数据结构,如果知道下标也可以直接进行访问,所以可以通过哈希函数将key映射成数组下标,进行访问)
  3. 冲突 不同的key经过hash函数运行后得到相同的值,产生冲突;
  4. 冲突解决方式
  5. 开放寻址:线性探测、二次探测、伪随机数序列(python的dict解决冲突用的这个,具体的策略没有看太明白)
  6. 再哈希法:将哈希值再哈希,然后存储;
  7. 链地址法:hash过后值相同的存储在链表里;
  8. 公共溢出区

python实现dict无序到有序:

  1. 原先的内存布局entries为哈希表,表中直接存储PyDictKeyEntry(hash、key、value),也就是说当当前位置为空的时候存的是(0, null, null)浪费了大量内存;

  2. python3.6: indices充当哈希表,存储的entries的index,使用index去访问存有PyDictKeyEntry的数组

python3 dict性能优化

节省存储空间:将存储PyDictKeyEntry的稀疏数组更改为存储int的稀疏数组; 之前的dict_entry是稀疏表,经压缩后在密集表上循环,使用更少的内存; 调整大小更快,并且触及更少的内存。 目前,每一个散列/键/值条目在一个过程中被移动或复制调整。 在新的布局中,只有索引是更新。 大多数情况下,散列/键/值条目从不移动(除了偶尔交换填充删除留下的空洞)。

range和xrange区别

range返回的是一个包含所有元素的列表,xrange返回的是一个生成器,生成器是一个可迭代对象,在对生成器进行迭代时,元素是逐个被创建的。而列表需要根据列表长度而开辟出相应的内存空间用来遍历,一般来看,在对大序列进行迭代的时候,因为xrange的特性,所以它会比较节约内存。