print a ... z, A ... Z, "\n"' in Python

Alex Martelli aleax at mac.com
Sun Mar 4 02:54:14 CET 2007


rzed <rzantow at gmail.com> wrote:

> aleax at mac.com (Alex Martelli) wrote in
> news:1hue4db.1ifwnsjmhm2pN%aleax at mac.com: 
> 
> > js  <ebgssth at gmail.com> wrote:
> > 
> >> HI guys,
> >> 
> >> How do you write Perl's
> >> 
> >>     print a ... z, A ... Z,  "\n"' in Python
> >> 
> >> In Python?
> > 
> > This specific one is easy, though this doesn't generalize:
> > 
> > import string
> > print string.lowercase + string.uppercase
> > 
> > For the general case, there's no way to avoid calling chr and
> > ord, because a string in Python doesn't have a "natural
> > successor". So the only issue is how you prefer to hide those
> > calls &c (in some class or function) and you already received
> > suggestions on that. 
> 
> No ord or chr in sight:
> 
> # Inclusive character range. 
> def pycrange(lo,hi):
>     import string
>     chars = string.letters + " "
>     rstr = ''
>     lp = chars.find(lo)
>     hp = chars.find(hi)
>     if lp < hp:    
>         rstr = chars[lp:hp+1]
>     return rstr
> 
> print pycrange('c','n')
> 
> 
> Lame code, though.

Very (the very existence of rstr and the if block are redundant, for
example; "return chars[lp:hp+1]" will already return an empty string
when lp > hp, and it's weird for the result to be empty for equal
arguments lo and hi when it's a length-two string for arguments, say,
'a' and 'b').

Also incorrect, presumably, since it would e.g. consider pycrange('w',
'C') to be 'wxyzABC', rather than empty (as an ord/chr based solution
would) or 'wxyz' (as I believe Perl does for 'w'...'C' -- one of those
black-magical Perl things, unless they've changed it recently) -- in
ASCII, uppercase letters come before lowercase ones, but in
string.letters they're vice versa.

Sure, you can get a complete 256-char ASCII alphabet with
alp=string.maketrans('', ''), use alp.find(x) as roughly equivalent to
ord(x) and alp[y] as roughly equivalent to chr(y), and thus (or by
sillier tricks yet) you wouldn't _formally_ "be calling chr and ord"
(you'd instead use roughly equivalent but slower and murkier idioms).
However, my point was: you can't avoid transforming from characters to
numbers and back again (ord and chr are just the "one obvious way" to do
that -- correct, if you want ASCII, readable, direct, and fast).  .find
and indexing (instead of ord and chr) do give you more flexibility (to
use an underlying order that's not ASCII's) should you need that; and
slicing an appropriate string does avoid an explicit loop.

(Just trying to forestall further silliness...): other ways to avoid
"calling chr and ord" include abusing modules struct and array.


Alex



More information about the Python-list mailing list