0

I have a function which returns a string of size N containing a random sequence of characters form a small set {A,B,C,D}. I generate this line as:

def gen_line(N):
  tline = ""
  for i in range(N):
    xrand = random.random()
    if( xrand < 0.25 ):
      ch = "A" 
    elif( xrand < 0.50 ):
      ch = "B" 
    elif( xrand < 0.75 ):
      ch = "C" 
    elif( xrand < 1.00 ):
      ch = "D" 
    else:
      print "ERROR: xrand = %f"%( xrand )
    tline = tline+ch
  return tline

but this is, no doubt, a very inefficient way to do things. Is there a better, more pythonic, way to accomplish this?

1
  • So your problem is not speed but how pythonic your solution is? Commented May 6, 2015 at 18:50

2 Answers 2

2

Try using random.choice with str.join.

>>> x = 'abcd'
>>> ''.join(random.choice(x) for _ in range(10))
'aabbdbadbc'
Sign up to request clarification or add additional context in comments.

3 Comments

@ndpu The problem with random.sample is that it samples without replacement. You will not be able to generate strings like 'aa'.
This is actually much slower. Why would that be? I am looking for a line of length 60, if it matters. It takes maybe twice as long.
@Laurbert515 There are several reasons why it could be slower, so I'm not sure. Benchmarks are often difficult to explain without rigorous testing and source code analysis. Instead of using random.choice, you could try n = len(x) - 1; ''.join(x[randint(0, n)] for _ in xrange(N)) Who knows, it could be faster or slower than other methods. Or just use np.random.choice from the other answer.
0

You can use np.random.choice:

In [13]:

import random
a = np.array(list('abcd'))
%timeit ''.join(np.random.choice(a, 10000))
​
def gen_line(N):
  tline = ""
  for i in range(N):
    xrand = random.random()
    if( xrand < 0.25 ):
      ch = "A" 
    elif( xrand < 0.50 ):
      ch = "B" 
    elif( xrand < 0.75 ):
      ch = "C" 
    elif( xrand < 1.00 ):
      ch = "D" 
    else:
      print("ERROR: xrand = %f"%( xrand ))
    tline = tline+ch
  return tline
​
%timeit gen_line(10000)
100 loops, best of 3: 6.39 ms per loop
100 loops, best of 3: 11.7 ms per loop

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.