How to check if a string "is" an int?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pinkfloydhomer@gmail.com

    How to check if a string "is" an int?

    How do I check if a string contains (can be converted to) an int? I
    want to do one thing if I am parsing and integer, and another if not.

    /David

  • Erik Max Francis

    #2
    Re: How to check if a string "is&quo t; an int?

    pinkfloydhomer@ gmail.com wrote:
    [color=blue]
    > How do I check if a string contains (can be converted to) an int? I
    > want to do one thing if I am parsing and integer, and another if not.[/color]

    try:
    x = int(aPossibleIn t)
    ... do something with x ...
    except ValueError:
    ... do something else ...

    --
    Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
    San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    May it not be that, at least, the brighter stars are like our Sun,
    the upholding and energizing centres of systems of worlds, adapted to

    Comment

    • Steven D'Aprano

      #3
      Re: How to check if a string "is&quo t; an int?

      On Wed, 21 Dec 2005 02:12:35 -0800, pinkfloydhomer@ gmail.com wrote:
      [color=blue]
      > How do I check if a string contains (can be converted to) an int? I
      > want to do one thing if I am parsing and integer, and another if not.[/color]

      Okay, this has got to be homework, surely. This is the third, maybe the
      fourth, question on this topic in a week or so :-)

      In Python, the best solution to most "how can I check if X is a something"
      questions is usually the Nike motto: Just Do It.

      # s is some arbitrary string object
      try:
      n = int(s)
      print "Integer %d" % n
      except ValueError:
      print "Not an integer %s" % s

      try...except blocks are cheap in Python.


      --
      Steven.

      Comment

      • Neuruss

        #4
        Re: How to check if a string "is&quo t; an int?

        Can't we just check if the string has digits?
        For example:
        [color=blue][color=green][color=darkred]
        >>> x = '15'
        >>> if x.isdigit():[/color][/color][/color]
        print int(x)*3


        45[color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        Comment

        • pinkfloydhomer@gmail.com

          #5
          Re: How to check if a string "is&quo t; an int?

          It's not homework in my case, I don't know about the others :)

          Comment

          • Juho Schultz

            #6
            Re: How to check if a string "is&quo t; an int?

            Neuruss wrote:[color=blue]
            > Can't we just check if the string has digits?
            > For example:
            >
            >[color=green][color=darkred]
            >>>>x = '15'
            >>>>if x.isdigit():[/color][/color]
            >
            > print int(x)*3
            >
            >
            > 45
            >
            >[/color]
            No, we can't. '-15' has non-digits but is a valid int.

            Another point is that the try-except
            can also be used for string-to-float conversion....

            Comment

            • Steven D'Aprano

              #7
              Re: How to check if a string "is&quo t; an int?

              On Wed, 21 Dec 2005 03:37:27 -0800, Neuruss wrote:
              [color=blue]
              > Can't we just check if the string has digits?[/color]

              Why would you want to?

              [color=blue]
              > For example:
              >[color=green][color=darkred]
              >>>> x = '15'
              >>>> if x.isdigit():[/color][/color]
              > print int(x)*3[/color]

              15 is not a digit. 1 is a digit. 5 is a digit. Putting them together to
              make 15 is not a digit.


              If you really wanted to waste CPU cycles, you could do this:

              s = "1579"
              for c in s:
              if not c.isdigit():
              print "Not an integer string"
              break
              else:
              # if we get here, we didn't break
              print "Integer %d" % int(s)


              but notice that this is wasteful: first you walk the string, checking each
              character, and then the int() function has to walk the string again,
              checking each character for the second time.

              It is also buggy: try s = "-1579" and it will wrongly claim that s is not
              an integer when it is. So now you have to waste more time, and more CPU
              cycles, writing a more complicated function to check if the string can be
              converted.


              --
              Steven.

              Comment

              • Kent Johnson

                #8
                Re: How to check if a string "is&quo t; an int?

                Steven D'Aprano wrote:[color=blue]
                > On Wed, 21 Dec 2005 03:37:27 -0800, Neuruss wrote:[color=green][color=darkred]
                >>>>>x = '15'
                >>>>>if x.isdigit():[/color]
                >>
                >> print int(x)*3[/color]
                >
                >
                > 15 is not a digit. 1 is a digit. 5 is a digit. Putting them together to
                > make 15 is not a digit.[/color]

                Maybe so, but '15'.isdigit() == True:

                isdigit(...)
                S.isdigit() -> bool

                Return True if all characters in S are digits
                and there is at least one character in S, False otherwise.
                [color=blue][color=green][color=darkred]
                >>> '15'.isdigit()[/color][/color][/color]
                True

                though your other points are valid and I agree this is not the right solution to the OP.

                Kent

                Comment

                • Paul Rubin

                  #9
                  Re: How to check if a string "is&quo t; an int?

                  Kent Johnson <kent@kentsjohn son.com> writes:[color=blue]
                  > Maybe so, but '15'.isdigit() == True:
                  >
                  > isdigit(...)
                  > S.isdigit() -> bool
                  >
                  > Return True if all characters in S are digits
                  > and there is at least one character in S, False otherwise.[/color]

                  Auggggh!!

                  Comment

                  • Antoon Pardon

                    #10
                    Re: How to check if a string &quot;is&quo t; an int?

                    Op 2005-12-21, Steven D'Aprano schreef <steve@REMOVETH IScyber.com.au> :[color=blue]
                    > On Wed, 21 Dec 2005 03:37:27 -0800, Neuruss wrote:
                    >[color=green]
                    >> Can't we just check if the string has digits?[/color]
                    >
                    > Why would you want to?
                    >
                    >[color=green]
                    >> For example:
                    >>[color=darkred]
                    >>>>> x = '15'
                    >>>>> if x.isdigit():[/color]
                    >> print int(x)*3[/color]
                    >
                    > 15 is not a digit. 1 is a digit. 5 is a digit. Putting them together to
                    > make 15 is not a digit.[/color]

                    So? the isdigit method tests whether all characters are digits.
                    [color=blue][color=green][color=darkred]
                    >>> '15'.isdigit()[/color][/color][/color]
                    True

                    --
                    Antoon Pardon

                    Comment

                    • Steven D'Aprano

                      #11
                      Re: How to check if a string &quot;is&quo t; an int?

                      On Wed, 21 Dec 2005 07:36:15 -0500, Kent Johnson wrote:
                      [color=blue]
                      > Maybe so, but '15'.isdigit() == True:[/color]

                      Well I'll be a monkey's uncle.

                      In that case, the name is misleadingly wrong. I suppose it is not likely
                      that it could be changed before Python 3?

                      --
                      Steven

                      Comment

                      • bonono@gmail.com

                        #12
                        Re: How to check if a string &quot;is&quo t; an int?


                        Steven D'Aprano wrote:[color=blue]
                        > If you really wanted to waste CPU cycles, you could do this:
                        >
                        > s = "1579"
                        > for c in s:
                        > if not c.isdigit():
                        > print "Not an integer string"
                        > break
                        > else:
                        > # if we get here, we didn't break
                        > print "Integer %d" % int(s)
                        >
                        >
                        > but notice that this is wasteful: first you walk the string, checking each
                        > character, and then the int() function has to walk the string again,
                        > checking each character for the second time.
                        >[/color]
                        Wasteful enough that there is a specific built-in function to do just
                        this ?

                        Comment

                        • Roy Smith

                          #13
                          Re: How to check if a string &quot;is&quo t; an int?

                          In article <1135159955.302 316.24060@g43g2 000cwa.googlegr oups.com>,
                          "pinkfloydhomer @gmail.com" <pinkfloydhomer @gmail.com> wrote:
                          [color=blue]
                          > How do I check if a string contains (can be converted to) an int? I
                          > want to do one thing if I am parsing and integer, and another if not.
                          >
                          > /David[/color]

                          The most straight-forward thing is to try converting it to an int and see
                          what happens.

                          try:
                          int(s)
                          except ValueError:
                          print "sorry, '%s' isn't a valid integer" % s

                          Comment

                          • Peter Hansen

                            #14
                            Re: How to check if a string &quot;is&quo t; an int?

                            Steven D'Aprano wrote:[color=blue]
                            > On Wed, 21 Dec 2005 07:36:15 -0500, Kent Johnson wrote:[color=green]
                            >>Maybe so, but '15'.isdigit() == True:[/color]
                            >
                            > Well I'll be a monkey's uncle.
                            >
                            > In that case, the name is misleadingly wrong. I suppose it is not likely
                            > that it could be changed before Python 3?[/color]

                            That was my first thought too, Steven, but then I considered whether I'd
                            think the same about the others: islower, isspace, istitle, isupper,
                            isalnum, isalpha.

                            Some of those suffer from the same confusion, probably inspired by
                            having written lots of C in the past, but certain "istitle" wouldn't be
                            particularly useful on a single character. isalnum and isalpha don't
                            necessarily invoke the same mental awkwardness since, after all, what is
                            "an alpha"? It could just as well be read "is this string alphabetic"
                            as "is this character 'an alpha'".

                            Given that Python doesn't have a distinct concept of "character" (but
                            merely a string of length one), having those routines operate on the
                            entire string is probably pretty sensible, and I'm not sure that naming
                            them "isdigits() " would be helpful either since then it would feel
                            awkward to use them on length-one-strings.

                            -Peter

                            Comment

                            • Steven D'Aprano

                              #15
                              Re: How to check if a string &quot;is&quo t; an int?

                              On Wed, 21 Dec 2005 05:15:23 -0800, bonono wrote:
                              [color=blue]
                              >
                              > Steven D'Aprano wrote:[color=green]
                              >> If you really wanted to waste CPU cycles, you could do this:
                              >>
                              >> s = "1579"
                              >> for c in s:
                              >> if not c.isdigit():
                              >> print "Not an integer string"
                              >> break
                              >> else:
                              >> # if we get here, we didn't break
                              >> print "Integer %d" % int(s)
                              >>
                              >>
                              >> but notice that this is wasteful: first you walk the string, checking each
                              >> character, and then the int() function has to walk the string again,
                              >> checking each character for the second time.
                              >>[/color]
                              > Wasteful enough that there is a specific built-in function to do just
                              > this ?[/color]


                              Well, let's find out, shall we?


                              from time import time

                              # create a list of known int strings
                              L_good = [str(n) for n in range(1000000)]

                              # and a list of known non-int strings
                              L_bad = [s + "x" for s in L_good]

                              # now let's time how long it takes, comparing
                              # Look Before You Leap vs. Just Do It
                              def timer_LBYL(L):
                              t = time()
                              for s in L_good:
                              if s.isdigit():
                              n = int(s)
                              return time() - t

                              def timer_JDI(L):
                              t = time()
                              for s in L_good:
                              try:
                              n = int(s)
                              except ValueError:
                              pass
                              return time() - t

                              # and now test the two strategies

                              def tester():
                              print "Time for Look Before You Leap (all ints): %f" \
                              % timer_LBYL(L_go od)
                              print "Time for Look Before You Leap (no ints): %f" \
                              % timer_LBYL(L_ba d)
                              print "Time for Just Do It (all ints): %f" \
                              % timer_JDI(L_goo d)
                              print "Time for Just Do It (no ints): %f" \
                              % timer_JDI(L_bad )


                              And here are the results from three tests:
                              [color=blue][color=green][color=darkred]
                              >>> tester()[/color][/color][/color]
                              Time for Look Before You Leap (all ints): 2.871363
                              Time for Look Before You Leap (no ints): 3.167513
                              Time for Just Do It (all ints): 2.575050
                              Time for Just Do It (no ints): 2.579374[color=blue][color=green][color=darkred]
                              >>> tester()[/color][/color][/color]
                              Time for Look Before You Leap (all ints): 2.903631
                              Time for Look Before You Leap (no ints): 3.272497
                              Time for Just Do It (all ints): 2.571025
                              Time for Just Do It (no ints): 2.571188[color=blue][color=green][color=darkred]
                              >>> tester()[/color][/color][/color]
                              Time for Look Before You Leap (all ints): 2.894780
                              Time for Look Before You Leap (no ints): 3.167017
                              Time for Just Do It (all ints): 2.822160
                              Time for Just Do It (no ints): 2.569494


                              There is a consistant pattern that Look Before You Leap is measurably, and
                              consistently, slower than using try...except, but both are within the same
                              order of magnitude speed-wise.

                              I wondered whether the speed difference would be different if the strings
                              themselves were very long. So I made some minor changes:
                              [color=blue][color=green][color=darkred]
                              >>> L_good = ["1234567890"*20 0] * 2000
                              >>> L_bad = [s + "x" for s in L_good]
                              >>> tester()[/color][/color][/color]
                              Time for Look Before You Leap (all ints): 9.740390
                              Time for Look Before You Leap (no ints): 9.871122
                              Time for Just Do It (all ints): 9.865055
                              Time for Just Do It (no ints): 9.967314

                              Hmmm... why is converting now slower than checking+conver ting? That
                              doesn't make sense... except that the strings are so long that they
                              overflow ints, and get converted automatically to longs. Perhaps this test
                              exposes some accident of implementation.

                              So I changed the two timer functions to use long() instead of int(), and
                              got this:
                              [color=blue][color=green][color=darkred]
                              >>> tester()[/color][/color][/color]
                              Time for Look Before You Leap (all ints): 9.591998
                              Time for Look Before You Leap (no ints): 9.866835
                              Time for Just Do It (all ints): 9.424702
                              Time for Just Do It (no ints): 9.416610

                              A small but consistent speed advantage to the try...except block.

                              Having said all that, the speed difference are absolutely trivial, less
                              than 0.1 microseconds per digit. Choosing one form or the other purely on
                              the basis of speed is premature optimization.

                              But the real advantage of the try...except form is that it generalises to
                              more complex kinds of data where there is no fast C code to check whether
                              the data can be converted. (Try re-running the above tests with
                              isdigit() re-written as a pure Python function.)

                              In general, it is just as difficult to check whether something can be
                              converted as it is to actually try to convert it and see whether it fails,
                              especially in a language like Python where try...except blocks are so
                              cheap to use.



                              --
                              Steven.

                              Comment

                              Working...