why does this unpacking work

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John Salerno

    #1

    why does this unpacking work

    I'm a little confused, but I'm sure this is something trivial. I'm
    confused about why this works:
    >>t = (('hello', 'goodbye'),
    ('more', 'less'),
    ('something', 'nothing'),
    ('good', 'bad'))
    >>t
    (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
    ('good', 'bad'))
    >>for x in t:
    print x


    ('hello', 'goodbye')
    ('more', 'less')
    ('something', 'nothing')
    ('good', 'bad')
    >>for x,y in t:
    print x,y


    hello goodbye
    more less
    something nothing
    good bad
    >>>
    I understand that t returns a single tuple that contains other tuples.
    Then 'for x in t' returns the nested tuples themselves.

    But what I don't understand is why you can use 'for x,y in t' when t
    really only returns one thing. I see that this works, but I can't quite
    conceptualize how. I thought 'for x,y in t' would only work if t
    returned a two-tuple, which it doesn't.

    What seems to be happening is that 'for x,y in t' is acting like:

    for x in t:
    for y,z in x:
    #then it does it correctly

    But if so, why is this? It doesn't seem like very intuitive behavior.

    Thanks.
  • johnzenger@gmail.com

    #2
    Re: why does this unpacking work

    It's just sequence unpacking. Did you know that this works?:

    pair = ("California"," San Francisco")
    state, city = pair
    print city
    # 'San Francisco'
    print state
    # 'California'

    John Salerno wrote:
    I'm a little confused, but I'm sure this is something trivial. I'm
    confused about why this works:
    >
    >>t = (('hello', 'goodbye'),
    ('more', 'less'),
    ('something', 'nothing'),
    ('good', 'bad'))
    >>t
    (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
    ('good', 'bad'))
    >>for x in t:
    print x
    >
    >
    ('hello', 'goodbye')
    ('more', 'less')
    ('something', 'nothing')
    ('good', 'bad')
    >>for x,y in t:
    print x,y
    >
    >
    hello goodbye
    more less
    something nothing
    good bad
    >>>
    >
    I understand that t returns a single tuple that contains other tuples.
    Then 'for x in t' returns the nested tuples themselves.
    >
    But what I don't understand is why you can use 'for x,y in t' when t
    really only returns one thing. I see that this works, but I can't quite
    conceptualize how. I thought 'for x,y in t' would only work if t
    returned a two-tuple, which it doesn't.
    >
    What seems to be happening is that 'for x,y in t' is acting like:
    >
    for x in t:
    for y,z in x:
    #then it does it correctly
    >
    But if so, why is this? It doesn't seem like very intuitive behavior.
    >
    Thanks.

    Comment

    • Carsten Haese

      #3
      Re: why does this unpacking work

      On Fri, 2006-10-20 at 15:14, John Salerno wrote:
      I'm a little confused, but I'm sure this is something trivial. I'm
      confused about why this works:
      >
      >>t = (('hello', 'goodbye'),
      ('more', 'less'),
      ('something', 'nothing'),
      ('good', 'bad'))
      >>t
      (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
      ('good', 'bad'))
      >>for x in t:
      print x
      >
      >
      ('hello', 'goodbye')
      ('more', 'less')
      ('something', 'nothing')
      ('good', 'bad')
      >>for x,y in t:
      print x,y
      >
      >
      hello goodbye
      more less
      something nothing
      good bad
      >>>
      >
      I understand that t returns a single tuple that contains other tuples.
      t doesn't "return" anything, t *is* a nested tuple.
      Then 'for x in t' returns the nested tuples themselves.
      It again doesn't "return" anything. It assigns each element of tuple t
      to x, one by one, executing the loop body for each element.
      But what I don't understand is why you can use 'for x,y in t' when t
      really only returns one thing. I see that this works, but I can't quite
      conceptualize how. I thought 'for x,y in t' would only work if t
      returned a two-tuple, which it doesn't.
      You're thinking of "x,y = t".
      What seems to be happening is that 'for x,y in t' is acting like:
      >
      for x in t:
      for y,z in x:
      #then it does it correctly
      No, it's actually behaving like

      for x in t:
      y,z = t
      # do something with y and z

      You seem to have difficulty distinguishing the concept of looping over a
      tuple from the concept of unpacking a tuple. This difficulty is
      compounded by the fact that, in your example above, you are looping over
      a tuple of tuples and unpacking each inner tuple on the fly.

      Hope this helps,

      Carsten.


      Comment

      • Carsten Haese

        #4
        Re: why does this unpacking work

        On Fri, 2006-10-20 at 15:37, Carsten Haese wrote:
        for x in t:
        y,z = t
        # do something with y and z
        Typo here, of course I mean y,z = x.

        -Carsten


        Comment

        • Jon Clements

          #5
          Re: why does this unpacking work


          John Salerno wrote:
          I'm a little confused, but I'm sure this is something trivial. I'm
          confused about why this works:
          >
          >>t = (('hello', 'goodbye'),
          ('more', 'less'),
          ('something', 'nothing'),
          ('good', 'bad'))
          >>t
          (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
          ('good', 'bad'))
          >>for x in t:
          print x
          >
          >
          ('hello', 'goodbye')
          ('more', 'less')
          ('something', 'nothing')
          ('good', 'bad')
          >>for x,y in t:
          print x,y
          >
          >
          hello goodbye
          more less
          something nothing
          good bad
          >>>
          >
          I understand that t returns a single tuple that contains other tuples.
          Then 'for x in t' returns the nested tuples themselves.
          >
          But what I don't understand is why you can use 'for x,y in t' when t
          really only returns one thing. I see that this works, but I can't quite
          conceptualize how. I thought 'for x,y in t' would only work if t
          returned a two-tuple, which it doesn't.
          >
          What seems to be happening is that 'for x,y in t' is acting like:
          >
          for x in t:
          for y,z in x:
          #then it does it correctly
          >
          But if so, why is this? It doesn't seem like very intuitive behavior.
          It makes perfect sense: in fact, you have kind of explained it
          yourself!

          Think of the for statement as returning the next element of some
          sequence; in this case it's a tuple. Then on the left side, the
          unpacking occurs. Using "for x in t", means that effectively no
          unpackig occurs, so you get the tuple. However, since the in is
          returning a tuple, using "for x,y in t", the tuple returned gets
          unpacked.

          Hope that helps.

          Jon.

          Comment

          • Gabriel Genellina

            #6
            Re: why does this unpacking work

            At Friday 20/10/2006 16:14, John Salerno wrote:
            >I'm a little confused, but I'm sure this is something trivial. I'm
            >confused about why this works:
            >
            >>t = (('hello', 'goodbye'),
            ('more', 'less'),
            ('something', 'nothing'),
            ('good', 'bad'))
            >I understand that t returns a single tuple that contains other tuples.
            >Then 'for x in t' returns the nested tuples themselves.
            >
            >But what I don't understand is why you can use 'for x,y in t' when t
            >really only returns one thing. I see that this works, but I can't quite
            >conceptualiz e how. I thought 'for x,y in t' would only work if t
            >returned a two-tuple, which it doesn't.
            You can think of

            for x in t:
            whatever

            as meaning "for each element contained in t, name it x and do whatever"

            The other concept involved is unpacking:
            >>w = (1,2,3)
            >>x,y,z = w
            >>x
            1

            When you say "for x,y in t:" there is an implicit unpacking, it means
            "for each element contained in t, unpack it into x and y and do whatever"
            >What seems to be happening is that 'for x,y in t' is acting like:
            >
            >for x in t:
            for y,z in x:
            #then it does it correctly
            No, it acts like:

            for w in t:
            x,y = w
            ...


            --
            Gabriel Genellina
            Softlab SRL

            _______________ _______________ _______________ _____
            Correo Yahoo!
            Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
            ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

            Comment

            • John Salerno

              #7
              Re: why does this unpacking work

              johnzenger@gmai l.com wrote:
              It's just sequence unpacking. Did you know that this works?:
              >
              pair = ("California"," San Francisco")
              state, city = pair
              print city
              # 'San Francisco'
              print state
              # 'California'
              Yes, I understand that. What confused me was if it had been written like
              this:

              pair = (("California", "San Francisco"))

              Comment

              • John Salerno

                #8
                Re: why does this unpacking work

                Carsten Haese wrote:
                You seem to have difficulty distinguishing the concept of looping over a
                tuple from the concept of unpacking a tuple.
                I think you're right. It's starting to make more sense now. I think when
                I saw:

                for x,y in t

                I was expecting 't' to be a two-tuple for it to work. Maybe writing it as:

                for (x,y) in t

                sort of helps to show that '(x,y)' is equivalent to one object in 't'.
                That makes it look a little more cohesive in my mind, I guess, or helps
                me to see it map out against 't' better.

                Comment

                • Marc 'BlackJack' Rintsch

                  #9
                  Re: why does this unpacking work

                  In <%ba_g.133$1n3. 3373@news.tufts .edu>, John Salerno wrote:
                  johnzenger@gmai l.com wrote:
                  >It's just sequence unpacking. Did you know that this works?:
                  >>
                  >pair = ("California"," San Francisco")
                  >state, city = pair
                  >print city
                  ># 'San Francisco'
                  >print state
                  ># 'California'
                  >
                  Yes, I understand that. What confused me was if it had been written like
                  this:
                  >
                  pair = (("California", "San Francisco"))
                  Uhm, you mean::

                  pair = (("California", "San Francisco"),)

                  Note the extra comma to make that "a tuple in a tuple".

                  Ciao,
                  Marc 'BlackJack' Rintsch

                  Comment

                  • Gabriel Genellina

                    #10
                    Re: why does this unpacking work

                    At Friday 20/10/2006 17:29, John Salerno wrote:
                    >I was expecting 't' to be a two-tuple for it to work. Maybe writing it as:
                    >
                    >for (x,y) in t
                    >
                    >sort of helps to show that '(x,y)' is equivalent to one object in 't'.
                    >That makes it look a little more cohesive in my mind, I guess, or helps
                    >me to see it map out against 't' better.
                    Note that it's the *comma* in an expression list what creates a
                    tuple, *not* the parens. A similar rule applies on the target side of
                    an assignment:

                    x,y = (1,2)
                    (x,y) = [1,2]
                    [x,y] = 1,2

                    and all variations are all equivalent.
                    The left part of a for statement is like an assignment.
                    With this in mind, it's not surprise that

                    for (x,y) in t: pass
                    for x,y in t: pass

                    are exactly the same.

                    <http://docs.python.org/ref/exprlists.html>
                    <http://docs.python.org/ref/assignment.html >


                    --
                    Gabriel Genellina
                    Softlab SRL

                    _______________ _______________ _______________ _____
                    Correo Yahoo!
                    Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
                    ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar

                    Comment

                    • John Salerno

                      #11
                      Re: why does this unpacking work

                      Marc 'BlackJack' Rintsch wrote:
                      Uhm, you mean::
                      >
                      pair = (("California", "San Francisco"),)
                      >
                      Note the extra comma to make that "a tuple in a tuple".
                      >
                      Ciao,
                      Marc 'BlackJack' Rintsch
                      You're right!

                      Comment

                      • Paddy

                        #12
                        Re: why does this unpacking work

                        John Salerno wrote:
                        I'm a little confused, but I'm sure this is something trivial. I'm
                        confused about why this works:
                        >
                        >>t = (('hello', 'goodbye'),
                        ('more', 'less'),
                        ('something', 'nothing'),
                        ('good', 'bad'))
                        >>t
                        (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
                        ('good', 'bad'))
                        >>for x in t:
                        print x
                        >
                        >
                        ('hello', 'goodbye')
                        ('more', 'less')
                        ('something', 'nothing')
                        ('good', 'bad')
                        >>for x,y in t:
                        print x,y
                        >
                        >
                        hello goodbye
                        more less
                        something nothing
                        good bad
                        >>>
                        >
                        I understand that t returns a single tuple that contains other tuples.
                        Then 'for x in t' returns the nested tuples themselves.
                        >
                        But what I don't understand is why you can use 'for x,y in t' when t
                        really only returns one thing. I see that this works, but I can't quite
                        conceptualize how. I thought 'for x,y in t' would only work if t
                        returned a two-tuple, which it doesn't.
                        >
                        Hi John,

                        Thats the point were you go astray.
                        iterating over t *does* produce a 2-tuple that can be unpacked
                        immediately.

                        maybe this will help, (notice that element is always one of the inner
                        tuples):
                        >>tpl = ((00,01), (10,11), (20,21))
                        >>for element in tpl:
                        .... print "tpl provides this when iterated over:", element
                        ....
                        tpl provides this when iterated over: (0, 1)
                        tpl provides this when iterated over: (10, 11)
                        tpl provides this when iterated over: (20, 21)
                        >>for element in tpl:
                        .... print "tpl provides this when iterated over:", element
                        .... sub0, sub1 = element
                        .... print "each element unpacks to:", sub0,"and:", sub1
                        ....
                        tpl provides this when iterated over: (0, 1)
                        each element unpacks to: 0 and: 1
                        tpl provides this when iterated over: (10, 11)
                        each element unpacks to: 10 and: 11
                        tpl provides this when iterated over: (20, 21)
                        each element unpacks to: 20 and: 21
                        >>for sub0, sub1 in tpl:
                        .... print "each element of tuple unpacked immediately to:",
                        sub0,"and:", sub1
                        ....
                        each element of tuple unpacked immediately to: 0 and: 1
                        each element of tuple unpacked immediately to: 10 and: 11
                        each element of tuple unpacked immediately to: 20 and: 21
                        >>>

                        - Paddy.

                        Comment

                        • Paddy

                          #13
                          Rate my reply

                          Hi,
                          In answering Johns question I had to approach it from a standpoint of
                          originally not seeing that their could be a difficulty; railing myself
                          in; then re-reading Johns question and trying even harder to put myself
                          in his shoes.
                          What I am interested in is if John and others might just take time out
                          to critique the replies. I'm interested in what the group think makes a
                          good comp.lang.pytho n reply: too short, too long; too cryptic, too
                          simplistic, too polite (is their such a thing), too nasty; too
                          self-effacing, too self-promoting; too long a sig ;-) , too anonymous
                          ....

                          Paddy wrote:
                          John Salerno wrote:
                          I'm a little confused, but I'm sure this is something trivial. I'm
                          confused about why this works:
                          >>t = (('hello', 'goodbye'),
                          ('more', 'less'),
                          ('something', 'nothing'),
                          ('good', 'bad'))
                          >>t
                          (('hello', 'goodbye'), ('more', 'less'), ('something', 'nothing'),
                          ('good', 'bad'))
                          >>for x in t:
                          print x


                          ('hello', 'goodbye')
                          ('more', 'less')
                          ('something', 'nothing')
                          ('good', 'bad')
                          >>for x,y in t:
                          print x,y


                          hello goodbye
                          more less
                          something nothing
                          good bad
                          >>>
                          I understand that t returns a single tuple that contains other tuples.
                          Then 'for x in t' returns the nested tuples themselves.

                          But what I don't understand is why you can use 'for x,y in t' when t
                          really only returns one thing. I see that this works, but I can't quite
                          conceptualize how. I thought 'for x,y in t' would only work if t
                          returned a two-tuple, which it doesn't.
                          >
                          Hi John,
                          >
                          Thats the point were you go astray.
                          iterating over t *does* produce a 2-tuple that can be unpacked
                          immediately.
                          >
                          maybe this will help, (notice that element is always one of the inner
                          tuples):
                          >
                          >tpl = ((00,01), (10,11), (20,21))
                          >for element in tpl:
                          ... print "tpl provides this when iterated over:", element
                          ...
                          tpl provides this when iterated over: (0, 1)
                          tpl provides this when iterated over: (10, 11)
                          tpl provides this when iterated over: (20, 21)
                          >for element in tpl:
                          ... print "tpl provides this when iterated over:", element
                          ... sub0, sub1 = element
                          ... print "each element unpacks to:", sub0,"and:", sub1
                          ...
                          tpl provides this when iterated over: (0, 1)
                          each element unpacks to: 0 and: 1
                          tpl provides this when iterated over: (10, 11)
                          each element unpacks to: 10 and: 11
                          tpl provides this when iterated over: (20, 21)
                          each element unpacks to: 20 and: 21
                          >for sub0, sub1 in tpl:
                          ... print "each element of tuple unpacked immediately to:",
                          sub0,"and:", sub1
                          ...
                          each element of tuple unpacked immediately to: 0 and: 1
                          each element of tuple unpacked immediately to: 10 and: 11
                          each element of tuple unpacked immediately to: 20 and: 21
                          >>
                          >
                          >
                          - Paddy.

                          Comment

                          • Fredrik Lundh

                            #14
                            Re: why does this unpacking work

                            John Salerno wrote:
                            I understand that t returns a single tuple that contains other tuples.
                            t *is* a single tuple that contains other tuples.
                            Then 'for x in t' returns the nested tuples themselves.
                            >
                            But what I don't understand is why you can use 'for x,y in t' when t
                            really only returns one thing. I see that this works, but I can't quite
                            conceptualize how.
                            hint:
                            >>t = (('hello', 'goodbye'),
                            .... ('more', 'less'),
                            .... ('something', 'nothing'),
                            .... ('good', 'bad'))
                            >>t[0]
                            ('hello', 'goodbye')
                            >>t[1]
                            ('more', 'less')
                            >>t[2]
                            ('something', 'nothing')
                            >>t[3]
                            ('good', 'bad')

                            </F>

                            Comment

                            • Bruno Desthuilliers

                              #15
                              Re: why does this unpacking work

                              John Salerno a écrit :
                              johnzenger@gmai l.com wrote:
                              >
                              >It's just sequence unpacking. Did you know that this works?:
                              >>
                              >pair = ("California"," San Francisco")
                              >state, city = pair
                              >print city
                              ># 'San Francisco'
                              >print state
                              ># 'California'
                              >
                              >
                              Yes, I understand that. What confused me was if it had been written like
                              this:
                              >
                              pair = (("California", "San Francisco"))

                              Python 2.4.1 (#1, Jul 23 2005, 00:37:37)
                              [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on
                              linux2
                              Type "help", "copyright" , "credits" or "license" for more information.
                              >>(("California ","San Francisco")) == ("California"," San Francisco")
                              True
                              pair = "California","S an Francisco"
                              >>pair
                              ('California', 'San Francisco')
                              >>t = 1,
                              >>t
                              (1,)
                              >>t = 1, 2
                              >>t
                              (1, 2)
                              >>>
                              HTH



                              Comment

                              Working...