Why would I get a TypeEror?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • It's me

    #1

    Why would I get a TypeEror?

    For this code snip:

    a=3
    .....
    b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]

    Why would I get a TypeError from the len function?

    Thanks,


  • Peter Hansen

    #2
    Re: Why would I get a TypeEror?

    It's me wrote:[color=blue]
    > For this code snip:
    >
    > a=3
    > ....
    > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
    >
    > Why would I get a TypeError from the len function?[/color]

    What did you expect the "length" of the integer 3 to be?

    -Peter

    Comment

    • harold fellermann

      #3
      Re: Why would I get a TypeEror?


      On 12.01.2005, at 18:35, It's me wrote:
      [color=blue]
      > For this code snip:
      >
      > a=3
      > ....
      > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
      >
      > Why would I get a TypeError from the len function?[/color]

      because len() works only for sequence and mapping objects:
      [color=blue][color=green][color=darkred]
      >>> help(len)[/color][/color][/color]
      Help on built-in function len in module __builtin__:

      len(...)
      len(object) -> integer

      Return the number of items of a sequence or mapping.

      - harold -

      --
      Ceci n'est pas une signature.
      --

      Comment

      • harold fellermann

        #4
        Re: Why would I get a TypeEror?


        On 12.01.2005, at 18:35, It's me wrote:
        [color=blue]
        > For this code snip:
        >
        > a=3
        > ....
        > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
        >
        > Why would I get a TypeError from the len function?[/color]

        the problem is, that (1,len(a)) is evaluated, neither what type a
        actually has
        (python has no builtin lazy evaluation like ML). You have to do it this
        way
        instead:

        a=3
        ....
        b = isinstance(a,(l ist,tuple,dict) ) and len(a) or 1

        - harold -

        --
        The opposite of a correct statement is a false statement.
        But the opposite of a profound truth may be another profound truth.
        -- Niels Bohr

        Comment

        • It's me

          #5
          Re: Why would I get a TypeEror?

          Sorry if my question was a little "lazy" and yes, I was asking about the
          "lazy evaluation". :=)

          I am surprised about this (and this can be dangerous, I guess).

          If this is true, I would run into trouble real quick if I do a:

          (1/x,1.0e99)[x==0]

          and that's not good.

          Something to keep in mind. :-(


          "harold fellermann" <harold.fellerm ann@upf.edu> wrote in message
          news:mailman.57 8.1105553620.22 381.python-list@python.org ...[color=blue]
          >
          > On 12.01.2005, at 18:35, It's me wrote:
          >[color=green]
          > > For this code snip:
          > >
          > > a=3
          > > ....
          > > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
          > >
          > > Why would I get a TypeError from the len function?[/color]
          >
          > the problem is, that (1,len(a)) is evaluated, neither what type a
          > actually has
          > (python has no builtin lazy evaluation like ML). You have to do it this
          > way
          > instead:
          >
          > a=3
          > ...
          > b = isinstance(a,(l ist,tuple,dict) ) and len(a) or 1
          >
          > - harold -
          >
          > --
          > The opposite of a correct statement is a false statement.
          > But the opposite of a profound truth may be another profound truth.
          > -- Niels Bohr
          >[/color]


          Comment

          • Steve Holden

            #6
            Re: Why would I get a TypeEror?

            It's me wrote:
            [color=blue]
            > For this code snip:
            >
            > a=3
            > .....
            > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
            >
            > Why would I get a TypeError from the len function?
            >
            > Thanks,
            >
            >[/color]
            because the interpreter evaluates the tuple (1, len(a)) before applying
            the indexing to it.

            You are trying to be far too clever. The standard way to write this
            would be:

            a = 3
            .....
            b = 1
            if isinstance(a,(l ist,tuple,dict) ):
            b = len(a)

            Is code length *really* so important? Think carefully ...

            regards
            Steve
            --
            Steve Holden http://www.holdenweb.com/
            Python Web Programming http://pydish.holdenweb.com/
            Holden Web LLC +1 703 861 4237 +1 800 494 3119

            Comment

            • Terry Reedy

              #7
              Re: Why would I get a TypeEror?


              "Peter Hansen" <peter@engcorp. com> wrote in message
              news:XOOdnSCB9N mJ-HjcRVn-2w@powergate.ca ...[color=blue]
              > What did you expect the "length" of the integer 3 to be?[/color]

              Perhaps 2 (bits in a minimal binary representation) .

              I once, for maybe a minute, considered proposing this as an overloaded
              meaning of len, but realized that that would more often mask errors than
              save time.

              If case bits(i) is what the OP wants:

              def bits(i):
              i = abs(i)
              b = 0
              while i:
              i >>= 1
              b += 1
              return b

              Terry J. Reedy



              Comment

              • Steven Bethard

                #8
                Re: Why would I get a TypeEror?

                It's me wrote:[color=blue]
                > For this code snip:
                >
                > a=3
                > ....
                > b=(1,len(a))[isinstance(a,(l ist,tuple,dict) )]
                >
                > Why would I get a TypeError from the len function?[/color]

                You're looking for lazy evaluation or short-circuiting behavior. Python
                provides one form of short circuiting behavior with 'and' and 'or',
                though you need to be careful. In your particular circumstances, you
                could write this code as:

                b = not isinstance(a, (list, tuple, dict)) and 1 or len(a)

                Some example code:

                py> def b(a):
                .... return not isinstance(a, (list, tuple, dict)) and 1 or len(a)
                ....
                py> b(3)
                1
                py> b([])
                0
                py> b([3, 4])
                2

                Note however that, due to how 'and' and 'or' short-circuit, you cannot
                write your code as:

                b = isinstance(a, (list, tuple, dict)) and len(a) or 1

                because when len(a) is 0, 1 will be returned instead of 0:

                py> def b(a):
                .... return isinstance(a, (list, tuple, dict)) and len(a) or 1
                ....
                py> b(3)
                1
                py> b([])
                1
                py> b([3, 4])
                2

                If you want lazy evaluation, you can do this with lambdas (though I
                wouldn't advise it):

                b = (lambda: 1, lambda: len(a))[isinstance(a,(l ist,tuple,dict) )]()

                Note that I select which function using isinstance as you have before,
                and then invoke the selected function with the final ().

                Steve

                Comment

                • Reinhold Birkenfeld

                  #9
                  Re: Why would I get a TypeEror?

                  It's me wrote:[color=blue]
                  > Sorry if my question was a little "lazy" and yes, I was asking about the
                  > "lazy evaluation". :=)
                  >
                  > I am surprised about this (and this can be dangerous, I guess).
                  >
                  > If this is true, I would run into trouble real quick if I do a:
                  >
                  > (1/x,1.0e99)[x==0]
                  >
                  > and that's not good.
                  >
                  > Something to keep in mind. :-([/color]

                  Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!

                  Reinhold

                  Comment

                  • It's me

                    #10
                    Re: Why would I get a TypeEror?

                    Say again???

                    "Reinhold Birkenfeld" <reinhold-birkenfeld-nospam@wolke7.n et> wrote in
                    message news:34ql1vF4dq d9pU1@individua l.net...[color=blue]
                    > It's me wrote:[color=green]
                    > > Sorry if my question was a little "lazy" and yes, I was asking about the
                    > > "lazy evaluation". :=)
                    > >
                    > > I am surprised about this (and this can be dangerous, I guess).
                    > >
                    > > If this is true, I would run into trouble real quick if I do a:
                    > >
                    > > (1/x,1.0e99)[x==0]
                    > >
                    > > and that's not good.
                    > >
                    > > Something to keep in mind. :-([/color]
                    >
                    > Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!
                    >
                    > Reinhold[/color]


                    Comment

                    • Reinhold Birkenfeld

                      #11
                      Re: Why would I get a TypeEror?

                      It's me wrote:[color=blue]
                      > Say again???
                      >
                      > "Reinhold Birkenfeld" <reinhold-birkenfeld-nospam@wolke7.n et> wrote in
                      > message news:34ql1vF4dq d9pU1@individua l.net...[color=green]
                      >> It's me wrote:[color=darkred]
                      >> > Sorry if my question was a little "lazy" and yes, I was asking about the
                      >> > "lazy evaluation". :=)
                      >> >
                      >> > I am surprised about this (and this can be dangerous, I guess).
                      >> >
                      >> > If this is true, I would run into trouble real quick if I do a:
                      >> >
                      >> > (1/x,1.0e99)[x==0]
                      >> >
                      >> > and that's not good.
                      >> >
                      >> > Something to keep in mind. :-([/color]
                      >>
                      >> Lazy evaluation: use the (x==0 and 1e99 or 1/x) form!
                      >>
                      >> Reinhold[/color][/color]

                      Say what again?

                      Reinhold

                      PS: Please do not produce top-posting!

                      Comment

                      • Steven Bethard

                        #12
                        Re: Why would I get a TypeEror?

                        It's me wrote:[color=blue]
                        > Say again???[/color]

                        Please stop top-posting -- it makes it hard to reply in context.
                        [color=blue]
                        > "Reinhold Birkenfeld" wrote...[color=green]
                        >>It's me wrote:[color=darkred]
                        >>>If this is true, I would run into trouble real quick if I do a:
                        >>>
                        >>>(1/x,1.0e99)[x==0][/color]
                        >>
                        >>Lazy evaluation: use the (x==0 and 1e99 or 1/x) form![/color][/color]

                        If you want short-circuting behavior, where only one of the two branches
                        gets executed, you should use Python's short-circuiting boolean
                        operators. For example,

                        (x == 0 and 1.0e99 or 1/x)

                        says something like:

                        Check if x == 0.
                        If so, check if 1.0e99 is non-zero. It is, so return it.
                        If x != 0, see if 1/x is non-zero. It is, so return it.

                        Note that if you're not comfortable with short-circuiting behavior, you
                        can also code this using lazy evaluation:

                        (lambda: 1/x, lambda: 1.0e99)[x==0]()

                        This says something like:

                        Create two functions, one to produce 1/x and one to produce 1.0e99.
                        Select one of these functions depending on whether or not x==0
                        Invoke the chosen function.

                        HTH,

                        Steve

                        Comment

                        • Reinhold Birkenfeld

                          #13
                          Re: Why would I get a TypeEror?

                          Steven Bethard wrote:[color=blue]
                          > It's me wrote:[color=green]
                          >> Say again???[/color]
                          >
                          > Please stop top-posting -- it makes it hard to reply in context.
                          >[color=green]
                          >> "Reinhold Birkenfeld" wrote...[color=darkred]
                          >>>It's me wrote:
                          >>>>If this is true, I would run into trouble real quick if I do a:
                          >>>>
                          >>>>(1/x,1.0e99)[x==0]
                          >>>
                          >>>Lazy evaluation: use the (x==0 and 1e99 or 1/x) form![/color][/color]
                          >
                          > If you want short-circuting behavior, where only one of the two branches
                          > gets executed, you should use Python's short-circuiting boolean
                          > operators. For example,
                          >
                          > (x == 0 and 1.0e99 or 1/x)
                          >
                          > says something like:
                          >
                          > Check if x == 0.
                          > If so, check if 1.0e99 is non-zero. It is, so return it.
                          > If x != 0, see if 1/x is non-zero. It is, so return it.
                          >
                          > Note that if you're not comfortable with short-circuiting behavior, you
                          > can also code this using lazy evaluation:
                          >
                          > (lambda: 1/x, lambda: 1.0e99)[x==0]()[/color]

                          Or even

                          (x==0 and lambda: 1e99 or lambda: 1/x)()

                          Or ...


                          Reinhold

                          Comment

                          • Stian Soiland

                            #14
                            Re: Why would I get a TypeEror?

                            På 14. jan 2005 kl. 22:58 skrev Steven Bethard:

                            (Any mac users? How do I fix this to appear in Norwegian? =)
                            [color=blue]
                            > Note that if you're not comfortable with short-circuiting behavior,
                            > you can also code this using lazy evaluation:
                            >
                            > (lambda: 1/x, lambda: 1.0e99)[x==0]()[/color]

                            ... and people wonder why so many Python people want to get rid of
                            Lambda =)

                            --
                            Stian Søiland You can't say civilization don't
                            Trondheim, Norway advance, however, for in every war
                            http://www.soiland.no/ they kill you in a new way. [Rogers]
                            =/\=

                            Comment

                            • Steven Bethard

                              #15
                              Re: Why would I get a TypeEror?

                              Stian Soiland wrote:[color=blue]
                              > På 14. jan 2005 kl. 22:58 skrev Steven Bethard:
                              >
                              > (Any mac users? How do I fix this to appear in Norwegian? =)
                              >[color=green]
                              >> Note that if you're not comfortable with short-circuiting behavior,
                              >> you can also code this using lazy evaluation:
                              >>
                              >> (lambda: 1/x, lambda: 1.0e99)[x==0]()[/color]
                              >
                              >
                              > .. and people wonder why so many Python people want to get rid of Lambda =)
                              >[/color]

                              Heh heh. No I don't. ;)

                              In fact, I don't ever use lambdas in any of my own "real" code. But I
                              don't mind being a little dirty when I post to c.l.py. ;) I guess I
                              could have written this as:

                              def inverse():
                              return 1/x
                              def largenum():
                              return 1.0e99
                              b = (inverse, largenum)[x==0]()

                              but I'm usually too lazy, and it's an ugly solution anyway, compared to
                              the simple one which the OP was apparently trying to avoid:

                              if x != 0:
                              b = 1/x
                              else:
                              b = 1.0e99

                              =)

                              Steve

                              Comment

                              Working...