A bit weird dictionary behavior

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pekka Laukkanen

    A bit weird dictionary behavior

    Hello,

    just noticed this:

    Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
    Type "help", "copyright" , "credits" or "license" for more information.
    >>{1: 2}
    {1: 2}
    >>{True: False}
    {True: False}
    >>{1: 2, True: False}
    {1: False}

    This must be because
    >>True == 1 and True in {1: 2}
    True

    but it still doesn't feel exactly right. Would it be worth submitting a bug?

    Cheers,
    .peke
  • Arnaud Delobelle

    #2
    Re: A bit weird dictionary behavior

    On 22 Sep, 10:25, "Pekka Laukkanen" <p...@iki.fiwro te:
    Hello,
    >
    just noticed this:
    >
    Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
    Type "help", "copyright" , "credits" or "license" for more information.>>{ 1: 2}
    {1: 2}
    >{True: False}
    {True: False}
    >{1: 2, True: False}
    >
    {1: False}
    >
    This must be because
    >
    >True == 1 and True in {1: 2}
    >
    True
    That's exactly the reason!
    but it still doesn't feel exactly right. Would it be worth submitting a bug?
    I don't think it can be considered as a bug, for the reason you gave
    above and because dictionary keys are by definition unique with
    respect to equality.

    Perhaps you could call it a "surprising feature" :)

    --
    Arnaud

    Comment

    • bearophileHUGS@lycos.com

      #3
      Re: A bit weird dictionary behavior

      Pekka Laukkanen:
      but it still doesn't feel exactly right. Would it be worth submitting a bug?
      It feels wrong because it is. In a tidier language (Pascal, Java, etc)
      a boolean and an integer must be different types. Keeping booleans and
      integers separated may avoid some bugs too (I don't know how many/
      often).
      But the Python language copies many things from C, where most things
      are chosen for practical purposes and maximum efficiency (and from
      much simpler Python implementations , where there was no boolean type,
      so bools are grafted in), so it's not a bug, and I think it will not
      be fixed soon (Python 3 was probably the last chance to change it, for
      several years to come).
      So you probably have to live with this illogical behavior.

      On the other hand it has some little practical advantages, you can do:
      sum(x == y for x in iterable)

      That also equals to a more tidy:
      sum(1 for x in iterable if x == y)

      Regarding the dict, they are dynamically typed, but good programming
      practice (that comes from experience of bugs that have bitten you)
      tells you that generally it's better to be careful with the inserting
      different types into a dict; often it's better to avoid doing it.

      Bye,
      bearophile

      Comment

      • bearophileHUGS@lycos.com

        #4
        Re: A bit weird dictionary behavior

        Tino Wildenhain:
        Wouldn't
        len([x for x in iterable if x==y])
        or even shorter:
        iterable.count( y)
        not work and read better anyway?
        The first version creates an actual list just to take its length,
        think about how much memory it may use.
        The second version requires the 'iterable' object to have a count()
        method, and in general this is false.

        even calculating with boolean values isn't neccessary
        since 'and' and 'foo if bar else blub' are working much better
        so the type coalescing
        bool - int - float can really go away.
        I don't understand.

        Bye,
        bearophile

        Comment

        • Carl Banks

          #5
          Re: A bit weird dictionary behavior

          On Sep 22, 3:43 pm, Bruno Desthuilliers
          <bdesth.quelque ch...@free.quel quepart.frwrote :
          bearophileH...@ lycos.com a écrit :
          >
          Pekka Laukkanen:
          but it still doesn't feel exactly right. Would it be worth submitting a bug?
          >
          It feels wrong because it is. In a tidier language (Pascal, Java, etc)
          a boolean and an integer must be different types.
          >
          Some would argue (and some did by the time Python grew a 'bool' type)
          that what is wrong is to have a bool type in a language that already
          have a wider definition of the truth value of an expression...
          And some would argue that it was wrong to have such a wide definition
          for the truth value of an expression in the first place...


          Carl Banks

          Comment

          • Grzegorz Staniak

            #6
            Re: A bit weird dictionary behavior

            On 22.09.2008, Carl Banks <pavlovevidence @gmail.comwrote d:
            >but it still doesn't feel exactly right. Would it be worth submitting a bug?
            >>
            It feels wrong because it is. In a tidier language (Pascal, Java, etc)
            a boolean and an integer must be different types.
            >>
            >Some would argue (and some did by the time Python grew a 'bool' type)
            >that what is wrong is to have a bool type in a language that already
            >have a wider definition of the truth value of an expression...
            >
            And some would argue that it was wrong to have such a wide definition
            for the truth value of an expression in the first place...
            Just out of idle curiosity, what could be the alternatives? Not to evaluate
            e.g. strings to "true"? Aren't such conventions as "whatever is not empty,
            is 'true'" popular in dynamic langauges?

            GS
            --
            Grzegorz Staniak <gstaniak _at_ wp [dot] pl>
            Nocturnal Infiltration and Accurate Killing

            Comment

            • Steven D'Aprano

              #7
              Re: A bit weird dictionary behavior

              On Mon, 22 Sep 2008 07:35:50 -0700, bearophileHUGS wrote:
              Tino Wildenhain:
              >
              >Wouldn't
              >len([x for x in iterable if x==y])
              >or even shorter:
              >iterable.count (y)
              >not work and read better anyway?
              >
              The first version creates an actual list just to take its length, think
              about how much memory it may use.
              For many iterables, the amount of memory is not excessive and the
              increase in readability of len() is to be preferred over the side-effect
              of sum(1 for...).

              But sure, in general you shouldn't try to count the number of items in an
              arbitrary iterable unless you know how much time and resources it will
              end up using. That's why I don't think len() should support arbitrary
              iterables.


              >even calculating with boolean values isn't neccessary since 'and' and
              >'foo if bar else blub' are working much better so the type coalescing
              >bool - int - float can really go away.
              >
              I don't understand.

              I think Tino means that you don't need to cast items to bool since you
              can use ints, floats etc. directly as truth values.



              --
              Steven

              Comment

              • Terry Reedy

                #8
                Re: A bit weird dictionary behavior

                Grzegorz Staniak wrote:
                On 22.09.2008, Carl Banks <pavlovevidence @gmail.comwrote d:
                >>Some would argue (and some did by the time Python grew a 'bool' type)
                >>that what is wrong is to have a bool type in a language that already
                >>have a wider definition of the truth value of an expression...
                >And some would argue that it was wrong to have such a wide definition
                >for the truth value of an expression in the first place...
                An alternate viewpoint is that only True and False 'have' a truth value.
                So whenever the interpreter *needs* a truth value for conditional and
                logical operations, and it has something else, it implicitly calls
                bool(ob) to get one. This, or possibly a shortcut version thereof, is
                what a Python interpreter effectively does.

                From this viewpoint, objecters would instead have to argue that it is
                wrong to have such implicit calls and that programmers should have to
                put them in explicitly.
                Just out of idle curiosity, what could be the alternatives? Not to evaluate
                e.g. strings to "true"? Aren't such conventions as "whatever is not empty,
                is 'true'" popular in dynamic langauges?
                I do not know what is popular, but implicit bool call are darn handy.

                tjr

                Comment

                • bearophileHUGS@lycos.com

                  #9
                  Re: A bit weird dictionary behavior

                  Steven D'Aprano:
                  >For many iterables, the amount of memory is not excessive and the increase in readability of len() is to be preferred over the side-effect of sum(1 for...).<
                  With side-effects do you mean the possibility of exhausting a lazy
                  iterable?

                  The readability difference is little, and it's way safer because it
                  works well enough with very long iterables too, so leniter(..) is
                  better than len(list(...)).

                  Bye,
                  bearophile

                  Comment

                  • Bruno Desthuilliers

                    #10
                    Re: A bit weird dictionary behavior

                    Carl Banks a écrit :
                    On Sep 22, 3:43 pm, Bruno Desthuilliers
                    <bdesth.quelque ch...@free.quel quepart.frwrote :
                    >bearophileH... @lycos.com a écrit :
                    >>
                    >>Pekka Laukkanen:
                    >>>but it still doesn't feel exactly right. Would it be worth submitting a bug?
                    >>It feels wrong because it is. In a tidier language (Pascal, Java, etc)
                    >>a boolean and an integer must be different types.
                    >Some would argue (and some did by the time Python grew a 'bool' type)
                    >that what is wrong is to have a bool type in a language that already
                    >have a wider definition of the truth value of an expression...
                    >
                    And some would argue that it was wrong to have such a wide definition
                    for the truth value of an expression in the first place...
                    Indeed !-)

                    Comment

                    • Lawrence D'Oliveiro

                      #11
                      Re: A bit weird dictionary behavior

                      In message <mailman.1385.1 222126198.3487. python-list@python.org >, Terry
                      Reedy wrote:
                      From this viewpoint, objecters would instead have to argue that it is
                      wrong to have such implicit calls and that programmers should have to
                      put them in explicitly.
                      But then again, you want to avoid unexpected restrictions like in Java,
                      where bool is a separate type, and while it is discrete, it cannot be used
                      to index arrays.

                      (Cf Pascal, where any discrete type could be used as an array index type.)

                      Comment

                      Working...