python知识备忘集合(持续更新)

======================deque=========================================
强化学习的experience replay 模块, 之前考虑到运行的速度,我一直用numpy数组实现,但用起来并不方便,代码也不简洁。用deque必然方便多了,但运行速度怎样?试过才知道。

from collections import deque
import time

d = deque(maxlen=1000000)

d.append('abc')
print d
d.extend([1,2,3])
print d
d.rotate(1)
print d
print d.count(1)
d.remove(2)
print d
d.pop()
print d

简单记录deque的主要操作,都很直观的。remove()方法会从左至右丢弃第一个匹配的对象。extend()方法可以添加一个序列(用list包装),rotate(1)方法类似于把队列中所有元素的序号+1

值得注意的是:和使用数组一样,可以使用d[0]方法读取和更改队列中元素的值。

from collections import deque
import time

d = deque(maxlen=1000000)

d.append('abc')
d.append('aaa')
print d[0]
d[0] = '666'
print d[0]
print d

关于deque的速度:
之前看过一些资料,说deque是双向的链表。那么我相信入队和出队的速度是迅速的。链表的问题在于增删查改队列中间的对象是很慢的。
1,增和删
deque没有直接在队列中间增加一个元素的方法,但可以通过rotate()方法调整队列中元素的序号,再使用append添加

from collections import deque
import time

d = deque(maxlen=1000000)

for i in xrange(1000000):
    d.append('aaa')


t1 = time.time()
d.rotate(500000)
t2 = time.time()
print t2 - t1
d.append('lll')
t3 = time.time()
print t3 - t2

结果是
0.000247955322266
2.40802764893e-05
因此,对于1000000个元素的队列,增和删的操作,在最差的情况下,在耗时在 104 量级

2,查和改

from collections import deque
import time

d = deque(maxlen=1000000)

for i in xrange(1000000):
    d.append('aaa')


t1 = time.time()
print d[500000]
t2 = time.time()
print t2 - t1

t3 = time.time()
d[500001] = '333'
t4 = time.time()
print t4 - t3

结果是:
0.00019097328186
0.00026798248291
对于1000000个元素的队列,在最坏的情况下,查和改的耗时在 104 量级

3,采样

from collections import deque
import time
import random

d = deque(maxlen=1000000)

for i in xrange(1000000):
    d.append('aaa')


t1 = time.time()

random.sample(d,64)
t2 = time.time()
print t2 - t1

结果是:0.0023889541626
random.sample()方法是未经优化的,用下面这个方法可以获得更快的速度

def sample(d,k):
    s_list = numpy.random.randint(0,len(d)*2/k,k).tolist()
    #print s_list
    result_list = []
    for i in s_list:
        d.rotate(i)
        result_list.append(d[0])
    return result_list

用这个方法耗时:0.00147318840027

以上时间的测量结果是有小幅波动的,并不十分精确

总结,1000000个元素,基本就是experience replay 的规模了。deque和list相比,优势在于1线程安全2从两段存取数据是O(1)速度。而list从左边存取是O(n)速度,从右边存取是O(1)速度。

猜你喜欢

转载自blog.csdn.net/qq_32231743/article/details/73199991
今日推荐