0

I put together this code which generates a string of 11 random printable ascii characters:

import random
foo=[]
for n in range(11):
    foo.append(chr(random.randint(32,126)))
print "".join(foo)

It works fine, but I can't help feel that there might be a more efficient way than calling "append" 11 times. Any tips in making it more Pythonic?

4 Answers 4

6

Use a list comprehension:

foo = [chr(random.randint(32,126)) for _ in xrange(11)]

You can combine that with the str.join():

print ''.join([chr(random.randint(32,126)) for _ in xrange(11)])

I've used xrange() here since you don't need the list produced by range(); only the sequence.

Quick demo:

>>> import random
>>> ''.join([chr(random.randint(32,126)) for _ in xrange(11)])
'D}H]qxfD6&,'
Sign up to request clarification or add additional context in comments.

7 Comments

Perfect. And now I'm learning about list comprehensions. Thanks!
you don't even need the [] in this case
@njzk2 str.join on a list has better performance as Martijn likes to point out... However, I reckon the above could be better still as str(bytearray(random.randint(32, 126) for _ in xrange(11)))
@njzk2: It is more efficient to use a list comprehension for a str.join() call than it is to use a generator expression. See list comprehension without [ ], Python
Bah - not much in it at all ;) (25.1u vs 24.1u)
|
0

You can do it using some functions to make your work more robust.

from random import randint

def random_ascii_string(length=11):
    return ''.join([random_ascii_char() for _ in range(length)])

def random_ascii_char():
    return chr(randint(32,126))

Using it:

>>> random_ascii_string(11)
'.K#d7#q d]%'

Comments

0

You don't need the intermediate step of putting it into a list:

import random
foo=''
for n in range(11):
    foo += chr(random.randint(32,126))
print foo

7 Comments

It was my understand that concatenating strings like that is less efficient.
I'd be surprised - they have to get concatenated one way or the other. Maybe using join is faster? I'll check.
I cProfile'd the OP's method vs my method. For 100,000 runs, the OP's join method took 4.2s, the string addition method here took 3.6s.
@Brionius: if you do it all at once with a join it can use one pass to figure out how long the resulting string is going to be and allocate the right amount of space from the start. Otherwise you'll have to do unnecessary copies and resizes. Compare ''.join(['a']*10000) with the loop equiv. (For small sizes you're just measuring the details of interpreter implementation which are hard to distinguish from noise.)
Yeah, that sounds reasonable.
|
0

The following will print the same thing as your method.

print ''.join(chr(random.randint(32,126)) for n in range(11))

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.