3

I'm trying to generate a random string using the elements of a different string, with the same length.

Ex) String: AGAACGC

I want a random string using only elements from the string above

Right now I have:

import random
seq = 'AGAACGC'
length = len(seq)    

for blah in range(len(seq)): #Apologies for the lame variable names
    x = random.randint(0,length - 1)
    print seq[x]

And of course this will give me something like:

A

A

G

A

C

A

A

How would I alter the program so that it prints out my random string on one line?

I'm hoping for a relatively simple answer, as I'm still a beginner in python, so I don't want to get too fancy. But any help at all would be appreciated.

And is there a way to repeat the randomization 'n' number of times?

Say instead of 1 random string, I wanted 4 random strings on different lines. Is there an easy way doing this? (My newbish mind is telling me to repeat the loop 'n' times...but it needs to be a changeable number of randomized strings)

Sorry for asking. I'd really appreciate some help. I'm stuck on a bigger problem because I don't know how to do these steps.

3
  • Do you want it on one line with spaces in between, or without? Commented Apr 29, 2015 at 0:26
  • Without spaces please! Thanks Commented Apr 29, 2015 at 0:29
  • 1
    As a side note, when Python forces you to give a name to something that you don't care about, instead of naming it blah, the usual convention is to name it _. (Unless you're using gettext or similar i18n, which gives a special meaning for _, in which case your project probably has its own convention—maybe __ or dummy—that you should follow.) Commented Apr 29, 2015 at 0:35

2 Answers 2

2

In Python 3, there is a simple way to print a character without a newline, but in Python 2, there isn't.* So, the simplest way to do this is to build up the string, then print it at the end:

result = ''
for blah in range(len(seq)): #Apologies for the lame variable names
    x = random.randint(0,length - 1)
    result += seq[x]
print result

* There are two less simple ways: You can use from __future__ import print_function and then use Python 3 print syntax instead of Python 2, or you can use sys.stdout.write(seq[x]) for each character and then sys.stdout.write('\n') and sys.stdout.flush() at the end. But I don't think you want either of those.


However, there are a number of ways to improve this:

  • Use randrange(length) instead of randint(0, length - 1).
  • Use random.choice(seq) instead of using randrange or randint in the first place.
  • Use _ instead of blah for "don't care" variables.*
  • If you don't care about what you're iterating over, just that you're iterating once for each character, just do for _ in seq:, not for _ in range(len(seq)):.
  • Build up a list of letters, then call ''.join() at the end, instead of building up a string.
  • Use a comprehension instead of an explicit loop.

Putting that all together:

print ''.join(random.choice(seq) for _ in seq)

* Unless you're using gettext for i18n, or something else that gives _ a special meaning. Most projects that do that come up with their own convention for "don't care" names—maybe __, or dummy. And of course blah would be fine for such a project, as long as you used it consistently.


As for repeating it, your newbish mind is right; just use a loop. For example (taking the second version, but it'll work just as well with the first):

n = 4
for _ in range(n):
    print ''.join(random.choice(seq) for _ in range(len(seq)))

That'll print out 4 different random strings. And if you set n to 100, it'll print 100 different random strings.

You may want to write this in a function:

def print_random_strings(seq, n):
    for _ in range(n):
        print ''.join(random.choice(seq) for _ in range(len(seq)))

And then you can call it like:

print_random_strings(seq, 4)

But either way, your basic intuition is right on track.

Sign up to request clarification or add additional context in comments.

5 Comments

I don't understand the aversion to __future__'s print_function. Seems like we should be encouraging beginners to use the new features. +1, otherwise.
@jpmc26: Well, I'd much rather people just learned Python 3 in the first place. But if someone is learning 2.7, it's presumably because they're using a book, online tutorial, class, or whatever that's geared to Python 2, which means using Python 3 features is just going to confuse them in the early stages of learning, as none of the print statements their book/site/teacher gives them will work right and they'll have no idea why…
@jpmc26: Also, just telling people "Python 3 makes this easy, Python 2 doesn't" seems like the best way to nudge them toward thinking about why they're learning Python 2, without being too obtrusive about it. Of course they may not have a choice (e.g., there's a Python 2 class as a requirement for their degree, or they're learning it to work as a junior dev maintaining a system built in Python 2, or whatever…).
I'm a bit stuck on how I could use the loop for the first version (my newbie version of the random string). How could I add the 'for' loop (in your example you used "for _ in range(n):") to the first version? I'm not too great with nested loops.
Just kidding I got it.
1

That's exactly what random.sample is meant for:

import random
seq = 'AGAACGC'

"".join(random.sample(seq, len(seq)))
# Gives you something like: 'CGAAACG'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.