[Tutor] finding a non-letter?

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Thu, 3 Oct 2002 00:08:35 -0700 (PDT)


On Thu, 3 Oct 2002, anthony polis wrote:

> I need to know if a string's first charcter is an integer. How would I
> do this?

Let's take a few concrete examples; let's look at strings whose first
characters look like numbers:

###
>>> words_starting_with_a_digit = [
...     "3v1l",
...     "4u",
...     "5\//33t"]
###


Because we're going to try writing something to check if a word starts
with a number, we have to do some negative tests too: we should think of
words that don't start with a number:

###
>>> words_starting_with_nondigit = [
...     "l33t",
...     "m3g4toky0.c0m"
...     ]
###

(Help!  I've been reading too much http://megatokyo.com.  Please forgive
me for the silly examples.  *grin*)



> I already know how to access the first character of a string by using
> str[0]
>
> but how would test to see if it's a non-letter?

What we can do is check, manually, if that character is either "0", or
"1", or "2", or...

###
def starts_with_a_digit(word):
    if word[0] == "0" or word[0] == "1" or word[0] == "2" or...
###

If we were determined enough to finish this function, it should work.
But we can do a lot to improve it.  One big way is to use the 'in'
operator.  Rather than build up that huge, bulky boring 'or' expression,
we can more simply check if some thing is "in" a collection:

###
def starts_with_a_digit(word):
    if word[0] in ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"):
        return 1
    return 0
###


And at least that fits on a few lines.  Does it work?

###
>>> for w in words_starting_with_a_digit + words_starting_with_nondigit:
...     print w, starts_with_a_digit(w)
...
3v1l 1
4u 1
5\//33t 1
l33t 0
m3g4toky0.c0m 0
###

Ok, yes, so we have what we were looking for.  Yah, we're done.



... but if we use a little more Python, we can write a better definition.
Let's keep going just for a little longer.  *grin*


Python treats strings as sequences too, so we can avoid constructing a
tuple, and instead act on the string "0123456789" directly:

###
def starts_with_a_digit(word):
    if word[0] in "0123456789":
        return 1
    return 0
###

The 'in' operator actually evaluates to either 1 or 0: it returns 1 if it
can find the element in the sequence, and 0 otherwise.


One other trick we can use is to avoid doing the 'if' altogther, and just
straight out use the result of 'in':

###
def starts_with_a_digit(word):
    return word[0] in "0123456789"
###


If we were still going at this beyond Uselessness, we can avoid typing out
that string of digits by borrowing a definition in the string module:

###
>>> string.digits
'0123456789'
>> def starts_with_a_digit(word):
...     return word[0] in string.digits
...
###



Best of wishes to you!