<dict>.setdefault()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tino Lange

    <dict>.setdefault()

    Hi!

    I just realized that <dict>.setdefau lt *always* executes the second
    argument - even if it's not necessary, because the requested item in
    the first argument exists.

    This is not what I expected - why evaluate the second argument if it's
    not needed? Also this can lead to side-effects!

    Example:
    [color=blue][color=green][color=darkred]
    >>> a = {}
    >>> b = {}
    >>> a.setdefault(1, b.setdefault(1, 1))[/color][/color][/color]
    1

    '1' didn't exist in a - so I expect 'b.setdefault(1 ,1)' to be
    evaluated. Great.
    [color=blue][color=green][color=darkred]
    >>> a.setdefault(1, b.setdefault(2, 1))[/color][/color][/color]
    1

    '1' existed, so it's not necessary to evaluate 'b.setdefault(2 ,1)'.
    But:
    [color=blue][color=green][color=darkred]
    >>> b[/color][/color][/color]
    {2: 1, 1: 1}

    .... shows that it was executed!

    So it's not equivalent to:

    if 1not in a:
    b.setdefault(2, 1)

    Is this really by design? If there's a complicated, expensive to
    calculate/build 2nd argument (maybe a function call) then it's also
    quite ineffective to evaluate it just to throw away...

    Thanks!

    Tino

  • Alexandre Fayolle

    #2
    Re: &lt;dict&gt;.se tdefault()

    Tino Lange a écrit :[color=blue]
    > I just realized that <dict>.setdefau lt *always* executes the second
    > argument - even if it's not necessary, because the requested item in
    > the first argument exists.[/color]

    Since setdefault is a method, this is coherent with Python's standard
    behaviour: method and function arguments are always evaluated before the
    method is called.

    --
    Alexandre Fayolle
    LOGILAB, Paris (France).
    http://www.logilab.com http://www.logilab.fr http://www.logilab.org
    Développement logiciel avancé - Intelligence Artificielle - Formations

    Comment

    • Tino Lange

      #3
      Re: &lt;dict&gt;.se tdefault()

      On Thu, 31 Jul 2003 16:54:46 +0000 (UTC), Alexandre Fayolle
      <alf@fayauffre. org> wrote:
      [color=blue][color=green]
      >> I just realized that <dict>.setdefau lt *always* executes the second
      >> argument - even if it's not necessary, because the requested item in
      >> the first argument exists.[/color][/color]
      [color=blue]
      > method and function arguments are always evaluated before the
      >method is called.[/color]

      Yep. You're right. Of course it's like that.
      Anyway - that's not what I expected in the first thought.

      It shows that less code is not always the best code...

      Thanks!

      Tino

      Comment

      • Tino Lange

        #4
        Re: &lt;dict&gt;.se tdefault()

        On 31 Jul 2003 18:01:51 +0100, jjl@pobox.com (John J. Lee) wrote:
        [color=blue]
        >Because that's the way Python always does function calls?[/color]

        Of course. From the consistency point of view... perfectly right!
        (I thought that maybe because these are very special low-level methods
        for built-in types, it might be different....)
        [color=blue]
        >Don't, then. :-) Use key in dict, or dict.has_key(ke y).[/color]

        or the C-like style:[color=blue][color=green][color=darkred]
        >>> a[3] = a.get(1) or b.setdefault(4, 1)[/color][/color][/color]

        Thanks!

        Tino

        Comment

        • Erik Max Francis

          #5
          Re: &lt;dict&gt;.se tdefault()

          Tino Lange wrote:
          [color=blue]
          > I just realized that <dict>.setdefau lt *always* executes the second
          > argument - even if it's not necessary, because the requested item in
          > the first argument exists.
          >
          > This is not what I expected - why evaluate the second argument if it's
          > not needed? Also this can lead to side-effects![/color]

          Because Python doesn't have macros or special forms that look like
          functions. If you see something that looks like a function, it
          evaluates all arguments before it calls the function. Always. Changing
          this would cause confusion, not resolve it.

          --
          Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
          __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
          / \ There's a reason why we / Keep chasing morning
          \__/ Sandra St. Victor

          Comment

          • Steven Taschuk

            #6
            Re: &lt;dict&gt;.se tdefault()

            Quoth Tino Lange:[color=blue]
            > On 31 Jul 2003 18:01:51 +0100, jjl@pobox.com (John J. Lee) wrote:[/color]
            [...][color=blue][color=green]
            > >Don't, then. :-) Use key in dict, or dict.has_key(ke y).[/color]
            >
            > or the C-like style:[color=green][color=darkred]
            > >>> a[3] = a.get(1) or b.setdefault(4, 1)[/color][/color][/color]

            Be careful doing that -- it relies on all possible values for a[1]
            being true. Consider:
            [color=blue][color=green][color=darkred]
            >>> a = {1: 0}
            >>> b = {}
            >>> a[3] = a.get(1) or b.setdefault(4, 1)
            >>> a[/color][/color][/color]
            {1: 0, 3: 1}[color=blue][color=green][color=darkred]
            >>> b[/color][/color][/color]
            {4: 1}

            --
            Steven Taschuk o- @
            staschuk@telusp lanet.net 7O )
            " (

            Comment

            Working...