我有一个看起来像这样的for循环,我希望让它更快。
mylist = range(100)
def normalrandom():
for a in range(100):
b = random.getrandbits(1)
if b==1: #do something with mylist[a]
我的列表有大约100个元素,我知道随机调用很贵。有没有一种更快的方法可以只进行一次随机调用,并获得100个随机布尔值?
编辑:这是迄今为止最好的解决方案。
def fastrandom():
s = list(range(100))
res = [i for i in s if random.random() >= .5]
for item in res:
#do something with mylist[item]
答案 0 :(得分:2)
这看起来效果很好。它返回一个生成器对象,因此唯一的内存使用量是n
- 位整数r
。
编辑:不要使用它!
import random
def rand_bools(n):
r = random.getrandbits(n)
return ( bool((r>>i)&1) for i in xrange(n) )
用法:
>>> for b in rand_bools(4): print b
...
False
True
False
True
它通过连续移位r
,屏蔽低位,并在每次迭代时将其转换为bool
来工作。
编辑:故事的寓意是对您的代码进行基准测试!在接受Blender的提示后,我写了以下测试:
import random
import time
def test_one(N):
a = 0
t0 = time.time()
for i in xrange(N):
if random.getrandbits(1): a += 1
return time.time() - t0
def rand_bools_int_func(n):
r = random.getrandbits(n)
return ( bool((r>>i)&1) for i in xrange(n) )
def test_generator(gen):
a = 0
t0 = time.time()
for b in gen:
if b: a += 1
return time.time() - t0
def test(N):
print 'For N={0}'.format(N)
print ' getrandbits(1) in for loop {0} sec'.format(test_one(N))
gen = ( not random.getrandbits(1) for i in xrange(N) )
print ' getrandbits(1) generator using not {0} sec'.format(test_generator(gen))
gen = ( bool(random.getrandbits(1)) for i in xrange(N))
print ' getrandbits(1) generator using bool() {0} sec'.format(test_generator(gen))
if (N < 10**6): # Way too slow!
gen = rand_bools_int_func(N)
print ' getrandbits(n) with shift/mask {0} sec'.format(test_generator(gen))
def main():
for i in xrange(3,8):
test(10**i)
if __name__ == '__main__':
main()
结果:
C:\Users\Jonathon\temp>python randbool.py
For N=1000
getrandbits(1) in for loop 0.0 sec
getrandbits(1) generator using not 0.0 sec
getrandbits(1) generator using bool() 0.0 sec
getrandbits(n) with shift/mask 0.0 sec
For N=10000
getrandbits(1) in for loop 0.00200009346008 sec
getrandbits(1) generator using not 0.00300002098083 sec
getrandbits(1) generator using bool() 0.00399994850159 sec
getrandbits(n) with shift/mask 0.0169999599457 sec
For N=100000
getrandbits(1) in for loop 0.0230000019073 sec
getrandbits(1) generator using not 0.029000043869 sec
getrandbits(1) generator using bool() 0.0380001068115 sec
getrandbits(n) with shift/mask 1.20000004768 sec
For N=1000000
getrandbits(1) in for loop 0.233999967575 sec
getrandbits(1) generator using not 0.289999961853 sec
getrandbits(1) generator using bool() 0.37700009346 sec
For N=10000000
getrandbits(1) in for loop 2.34899997711 sec
getrandbits(1) generator using not 2.89400005341 sec
getrandbits(1) generator using bool() 3.76900005341 sec
总之,我的回答是“有趣的*解决方案,但不要使用它!简单地使用random.getrandbits(1)
要快得多。
答案 1 :(得分:0)
如何生成随机二进制字符串
import random
rand_sequence = [random.randint(0, 1) for x in range(100)]
然后通过索引
访问字符串数组for i in range(len(rand_sequence)):
if bool(rand_sequence [i]):
# do something here
或者,您可以从set(0,1)以及
生成一串随机整数rand_sequence = str(bin(random.getrandbits(100)))[2:].zfill(100)
答案 2 :(得分:0)
以下是不同方法的一些时间安排:
代码:
from random import getrandbits, randint, random, sample
s = list(range(100))
def loop_bits():
res = []
b = getrandbits(len(s))
for i in s:
if b % 2 == 0:
res.append(i)
b >>= 1
def comp_bits():
res = [i for i in s if getrandbits(1)]
def comp_randint():
res = [i for i in s if randint(0, 1)]
def comp_random():
res = [i for i in s if random() >= .5]
不同交互者的结果:
$ python2.7 -m timeit -s 'import randtest' 'randtest.loop_bits()'
10000 loops, best of 3: 97.7 usec per loop
$ python2.7 -m timeit -s 'import randtest' 'randtest.comp_bits()'
10000 loops, best of 3: 55.6 usec per loop
$ python2.7 -m timeit -s 'import randtest' 'randtest.comp_randint()'
1000 loops, best of 3: 306 usec per loop
$ python2.7 -m timeit -s 'import randtest' 'randtest.comp_random()'
10000 loops, best of 3: 25.5 usec per loop
$
$ pypy -m timeit -s 'import randtest' 'randtest.loop_bits()'
10000 loops, best of 3: 44 usec per loop
$ pypy -m timeit -s 'import randtest' 'randtest.comp_bits()'
10000 loops, best of 3: 41 usec per loop
$ pypy -m timeit -s 'import randtest' 'randtest.comp_randint()'
100000 loops, best of 3: 14.4 usec per loop
$ pypy -m timeit -s 'import randtest' 'randtest.comp_random()'
100000 loops, best of 3: 12.7 usec per loop
$
$ python3 -m timeit -s 'import randtest' 'randtest.loop_bits()'
10000 loops, best of 3: 53.7 usec per loop
$ python3 -m timeit -s 'import randtest' 'randtest.comp_bits()'
10000 loops, best of 3: 48.9 usec per loop
$ python3 -m timeit -s 'import randtest' 'randtest.comp_randint()'
1000 loops, best of 3: 436 usec per loop
$ python3 -m timeit -s 'import randtest' 'randtest.comp_random()'
10000 loops, best of 3: 22.2 usec per loop
所以,在所有情况下,最后一次(使用random.random()
的理解是迄今为止最快的。
答案 3 :(得分:0)
试试这个:
mylist = range(100)
todolist= filter(lambda x: random.getrandbits(1),mylist)
todolist
[0, 4, 7, 8, 11, 13, 15, 16, 20, 21, 22, 23, 24, 25, 29, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 52, 53, 54, 56, 59, 64, 67, 68, 70, 71, 80, 81, 82, 85, 89, 90, 93, 95, 96, 97, 99]
len(todolist)
46
for item in todolist : do_work(item)
答案 4 :(得分:0)
把这个放在这里让我将来找到......
import random
def random_array(i):
return [bool(random.getrandbits(1)) for i in range(i)]
用法:
>>> random_array(10)
[False, False, True, True, True, True, True, True, True, False]
>>> random_array(10)
[False, True, True, False, False, True, True, True, False, True]
>>> random_array(10)
[False, True, False, False, True, True, True, True, False, True]