0x00 memoryview for Python3
用于操作大数据,不用复制他们就可以操作
>>> import array
>>> numbers = array.array('d',[-2,-1,0,1,2])
>>> memv = memoryview(numbers)
>>> len(memv)
5
>>> memv_oct=memv.cast('B')
>>> memv_oct.tolist()
[0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 240, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64]
>>> numbers
array('d', [-2.0, -1.0, 0.0, 1.0, 2.0])
>>> memv_oct[5]=4
>>> numbers
array('d', [-2.001953125, -1.0, 0.0, 1.0, 2.0])
>>> memv_oct.tolist()
[0, 0, 0, 0, 0, 4, 0, 192, 0, 0, 0, 0, 0, 0, 240, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64]
python array文档中typecode的表格
0x02 numpy黑魔法 操作array
>>> import numpy
>>> a= numpy.arange(12)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> a.shape
(12,)
>>> a.shape=3,4
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[2]
array([ 8, 9, 10, 11])
>>> a[2,1]
9
>>> a[:,1]
array([1, 5, 9])
>>> a[:,1]
array([1, 5, 9])
>>> a.transpose() 矩阵转置
array([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])
0x03队列操作 Deques和其他队列
-
从list的左边做删除和插入都很消耗资源,整个list都会改变,collections.deque 是一个线程安全的双端队列,为两端快速插入删除而设计。
-
一个deque可以有边界 往满队列 添加新元素时,队列从另一端丢弃元素。
-
deque在处理删除中间元素的时不快,主要优化在pop和append。
-
append和pop_left是原子级的操作,deque可以放心的应用于多线程程序中,不用加线程锁。
python中其它应用deque的地方对比
1、queue 同样的线程安全,但是当队列满时的处理方式和deque不同,不会丢弃另一项,而是等待线程腾出空间来,可以用于限制线程的数量。
2、multiprocessing 使用自己的边界队列,和queue很像 为inter-process 程序设计
3、asyncio 适合异步编程 提供Queue , LifoQueue , PriorityQueue and JoinableQueue的API接口 底层是deque和multiprocessing
4、heapq 和前三个模块不一样 它并没有实现一个队列类,但是提供了heappush,heappop方法,让你把可变序列像队列一样使用
>>> from collections import deque
>>> dq =deque(range(10),maxlen=10)
>>> dq
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> dq.rotate(3)
>>> dq
deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
>>> dq.rotate(-4)
>>> dq
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10)
>>> dq.extend([4,11,22])
>>> dq
deque([3, 4, 5, 6, 7, 8, 9, 4, 11, 22], maxlen=10)
>>> dq.extendleft(['h','h','a']) # 像左扩展的顺序是反的
>>> dq
deque(['a', 'h', 'h', 3, 4, 5, 6, 7, 8, 9], maxlen=10)
0x04 bisect
>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect(breakpoints, score)
return grades[i]
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
0x05小结
-
*= 和 += 对可变序列和不可变序列有区别 ,不可变序列会创建一个新的序列,不可变序列通常会原地更改,主要看序列的实现。
-
sort和sorted很方便。要维持一个序列有序使用bisect.insort ,高效的查找用bisect.bisect
-
Some objects contain references to other objects; these are called containers.
l = [28, 14, '28', 5, '9', '1', 0, 6, '23', 19]
sorted(l, key=int)
> [0, '1', 5, 6, '9', 14, 19, '23', 28, '28']
0x06 什么是可hash
先引用官方文档的说法
An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash() method), and can be compared to other objects (it needs an
eq() method). Hashable objects which compare equal must have the same hash value. [...]
-
原子可变的类型都是可hash的,例如str 、bytes 和数字类型
-
frozenset 天生可hash
-
tuple 能不能hash得看他的每个元素,是不是可hash
dict
dict生成
OrderDict 和defaultdict
setdefault是一个巧妙的映射方法,用得好可以避免key的冗余