Avoiding local variable declarations?

Paul McGuire ptmcg at austin.rr.com
Fri Nov 14 01:32:32 CET 2008


On Nov 13, 2:32 pm, "Chris Mellon" <arka... at gmail.com> wrote:
> On Thu, Nov 13, 2008 at 2:22 PM, dpapathanasiou
>
>
>
>
>
> <denis.papathanas... at gmail.com> wrote:
> > I have some old Common Lisp functions I'd like to rewrite in Python
> > (I'm still new to Python), and one thing I miss is not having to
> > declare local variables.
>
> > For example, I have this Lisp function:
>
> > (defun random-char ()
> >  "Generate a random char from one of [0-9][a-z][A-Z]"
> >  (if (< 50 (random 100))
> >      (code-char (+ (random 10) 48)) ; ascii 48 = 0
> >      (code-char (+ (random 26) (if (< 50 (random 100)) 65 97))))) ;
> > ascii 65 = A, 97 = a
>
> > My Python version looks like this:
>
> > def random_char ():
> >    '''Generate a random char from one of [0-9][a-z][A-Z]'''
> >    if random.randrange(0, 100) > 50:
> >        return chr( random.randrange(0, 10) + 48 ) # ascii 48 = 0
> >    else:
> >        offset = 65 # ascii 65 = A
> >        if random.randrange(0, 100) > 50:
> >            offset = 97 # ascii 97 = a
> >        return chr( random.randrange(0, 26) + offset )
>
> > Logically, it's equivalent of the Lisp version.
>
> > But is there any way to avoid using the local variable (offset) in the
> > Python version?
>
> Any time you port between languages, it's rarely a good idea to just
> convert code verbatim. For example:
>
> import random, string
> def random_char():
>     return random.choice(string.ascii_letters + string.digits)- Hide quoted text -
>
> - Show quoted text -

Not quite.  The original Lisp function first flips a coin to see if a
digit or alpha should be returned.  If alpha, then flips a coin again
to see if upper or lower case should be returned.  The alpha branch
could be collapsed into just returning a random selection from [A-Za-
z], but if you combine the alpha and numeric branches, you have less
than a 1/3 chance of getting a digit, vs. the 50-50 chance of the
original Lisp code.

Try this:

import random
import string
coinflip = lambda : int(random.random()*2)
if coinflip():
    return random.choice(string.digits)
else:
    return random.choice(string.ascii_letters)

or just:

return random.choice( (string.digits, string.ascii_letters)[coinflip
()] )

-- Paul



More information about the Python-list mailing list