Should: "for k,v in **dictionary_instance" work?

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

    #1

    Should: "for k,v in **dictionary_instance" work?

    Does it make sense to provide this syntax for iterating key/value
    pairs from a dictionary?

    for k,v in **dict():
    print k,v

    why is this not the same as:

    for k,v in dict().items():
    print k,v

    for that matter, why the heck doesn't a dictionary default to
    returning a tuple
    k,v pair from its iterator?

    Pax, Keith

    Ps, I'm sure someone has thought of these things before, probably been
    answered before, but I'm sure I didn't find reference to them when i
    searched.

  • Marc 'BlackJack' Rintsch

    #2
    Re: Should: "for k,v in **dictionary_in stance" work?

    In <1181935045.323 196.287810@n2g2 000hse.googlegr oups.com>, keithgabryelski
    wrote:
    Does it make sense to provide this syntax for iterating key/value
    pairs from a dictionary?
    >
    for k,v in **dict():
    print k,v
    >
    why is this not the same as:
    >
    for k,v in dict().items():
    print k,v
    Why should it be? Why adding something that unreadable and magic instead
    of the perfect readable ``for k, v in some_dict.iteri tems():``?

    And I don't see why it should be ``**``!?

    Ciao,
    Marc 'BlackJack' Rintsch

    Comment

    • Dustan

      #3
      Re: Should: &quot;for k,v in **dictionary_in stance&quot; work?

      On Jun 15, 2:17 pm, keithgabryel... @gmail.com wrote:
      Does it make sense to provide this syntax for iterating key/value
      pairs from a dictionary?
      >
      for k,v in **dict():
      print k,v
      >
      why is this not the same as:
      >
      for k,v in dict().items():
      print k,v
      >
      for that matter, why the heck doesn't a dictionary default to
      returning a tuple
      k,v pair from its iterator?
      >
      Pax, Keith
      >
      Ps, I'm sure someone has thought of these things before, probably been
      answered before, but I'm sure I didn't find reference to them when i
      searched.
      The answer is simply for history and for clarity.

      Comment

      • Steven D'Aprano

        #4
        Re: Should: &quot;for k,v in **dictionary_in stance&quot; work?

        On Fri, 15 Jun 2007 19:17:25 +0000, keithgabryelski wrote:
        Does it make sense to provide this syntax for iterating key/value
        pairs from a dictionary?
        >
        for k,v in **dict():
        print k,v
        >
        why is this not the same as:
        >
        for k,v in dict().items():
        print k,v
        Because *t and **d already have well-defined meanings, and that's not
        what **d would mean.

        In a function definition, *t collects positional arguments into a tuple
        and **d collects keyword arguments into a dictionary. In a function call,
        they expand them again. For example:

        function(1, 2, 3, a=4, b=5, c=6)
        ==t = (1, 2, 3); d = {'a':4, 'b':5, 'c':6}

        function(*t, **d)
        ==function(1, 2, 3, a=4, b=5, c=6)


        Currently, *t and **d are syntax errors outside of function calls and
        definitions. (Any other places?) But if they were allowed, what would they
        mean? For consistency, we would expect the following:

        t = tuple(1, 2, 3)
        for item in *t:
        # same as "for item in 1, 2, 3:"
        print item


        Even if it were allowed, it would be pointless: it would just expand the
        tuple only to collect it again.

        What would **d mean?

        d = dict(a=1, b=2, c=3)
        for key, value in **d:
        # same as "for key, value in 'a': 1, 'b': 2, 'c': 3:"
        print key, value


        For starters, that would mean changing the syntax of Python to allow
        key:value assignments outside of a dict constructor. I can't think of a
        reason to do so, but even if there is, we have the same problem as for the
        tuple expansion: it would pointlessly expand the dict, only to collect it
        again.

        Maybe you don't care about consistency and you just want the compiler to
        accept "for k,v in **d" as syntactic sugar for "for k,v in d.items()". Or
        perhaps d.iteritems() would be a better choice.

        In that case, Python isn't very big on syntactic sugar merely for saving a
        few characters of typing, so you're unlikely to convince those who would
        need convincing.

        for that matter, why the heck doesn't a dictionary default to
        returning a tuple
        k,v pair from its iterator?
        When dictionaries were first made iterable, in Python 2.2 if I recall
        correctly, there was debate about whether "for thing in dict:" should be
        equivalent to iterating over the keys, the values or both. In particular,
        people pointed out that there were just as many, or slightly more,
        examples of "for k,v in dict.items()" as "for k in dict.keys()" in the
        standard library. So there is a good case for making iterating over a
        dictionary equivalent to iterating over the keys and values.

        But the deciding point was the correspondence between "for x in dict" and
        "if x in dict". In fact, Python then, and now, included a fall-back
        iterator protocol: if __getitem__ is defined, iteration over an object is
        equivalent to repeatedly calling __getitem__.

        You can read the PEP that covers some of these issues here:





        --
        Steven.

        Comment

        • irstas@gmail.com

          #5
          Re: Should: &quot;for k,v in **dictionary_in stance&quot; work?

          On Jun 16, 5:27 am, Steven D'Aprano
          <s...@REMOVE.TH IS.cybersource. com.auwrote:
          Currently, *t and **d are syntax errors outside of function calls and
          definitions. (Any other places?) But if they were allowed, what would they
          mean?
          Actually since you asked, I had to try this out

          x = range(10)
          a, *b = x

          I would take it to mean a = x[0], b = x[1:] (or more precicely, it
          would
          probaby have to use the iter protocol). Unfortunately it fails..
          Since these are roughly equivalent:

          t = 1, (2, 3)

          a, (b, c) = t

          def foo(a, (b, c)): print a,b,c
          foo(*t)

          I would like to see the assignment enhanced so that this works too

          t = 1, (2, 3), 4, 5

          a, (b, c), *d = t

          def foo(a, (b, c), *d): print a,b,c,d
          foo(*t)

          The latter one with function definition works fine, the former
          assignment doesn't (SyntaxError). It's a bit surprising. Is there
          any reason not to support this syntax? It would be neatly symmetric
          in my opinion, so one wouldn't have to learn anything new. In fact,
          this addition would reduce the amount of things one must learn
          (unexpected behaviour).

          def rawr((a, b, (c, *d)), (e, *f), **g): pass

          Comment

          • Eduardo \EdCrypt\ O. Padoan

            #6
            Re: Should: &quot;for k,v in **dictionary_in stance&quot; work?

            Actually since you asked, I had to try this out
            >
            x = range(10)
            a, *b = x
            PEP 3132: Extended Iterable Unpacking
            This PEP proposes a change to iterable unpacking syntax, allowing to specify a “catch-all” name which will be assigned a list of all items not assigned to a “regular” name.




            --
            EduardoOPadoan (eopadoan->altavix::com )
            Bookmarks: http://del.icio.us/edcrypt

            Comment

            Working...