unpacking with default values

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

    unpacking with default values

    Hi all,

    probably a dumb question, but I didn't find something elegant for my
    problem so far.
    In perl you can unpack the element of a list to variables similar as
    in python
    (a, b, c = [0, 1, 2]), but the number of variables need not to fit the
    number
    of list elements.
    That means, if you have less list elements variables are filled with
    'undef' (None in python), if you have more list elements as necessary
    the rest is ignored.

    How can I achieve this behaviour with python in an elegant and fast
    way?

    Best regards
    Andreas Mock
  • Gary Herron

    #2
    Re: unpacking with default values

    McA wrote:
    Hi all,
    >
    probably a dumb question, but I didn't find something elegant for my
    problem so far.
    In perl you can unpack the element of a list to variables similar as
    in python
    (a, b, c = [0, 1, 2]), but the number of variables need not to fit the
    number
    of list elements.
    That means, if you have less list elements variables are filled with
    'undef' (None in python), if you have more list elements as necessary
    the rest is ignored.
    >
    How can I achieve this behaviour with python in an elegant and fast
    way?
    >
    Best regards
    Andreas Mock
    --

    >
    Python 3.0 has something a bit like this. Excess values can be bound
    (as a list) to the last variable:

    a,b,*c = [1,2,3,4,5]

    will result in c containing [3,4,5].

    In Python 2.x, you can't do that directly, but you should be able to
    create a function that lengthens or shortens an input tuple of arguments
    to the correct length so you can do:

    a,c,b = fix(1,2)
    d,e,f = fix(1,2,3,4)

    However, the function won't know the length of the left hand side
    sequence, so it will have to be passed in as an extra parameter or hard
    coded.


    Gary Herron

    Comment

    • McA

      #3
      Re: unpacking with default values

      On 17 Jul., 18:33, Gary Herron <gher...@island training.comwro te:
      >
      In Python 2.x, you can't do that directly, but you should be able to
      create a function that lengthens or shortens an input tuple of arguments
      to the correct length so you can do:
      >
      a,c,b = fix(1,2)
      d,e,f = fix(1,2,3,4)
      >
      However, the function won't know the length of the left hand side
      sequence, so it will have to be passed in as an extra parameter or hard
      coded.
      Hi Gary,

      thank you for the answer.
      Do you know the "protocol" used by python while unpacking?
      Is it a direct assingnment? Or iterating?

      Best regards
      Andreas Mock

      Comment

      • Gary Herron

        #4
        Re: unpacking with default values

        McA wrote:
        On 17 Jul., 18:33, Gary Herron <gher...@island training.comwro te:
        >
        >In Python 2.x, you can't do that directly, but you should be able to
        >create a function that lengthens or shortens an input tuple of arguments
        >to the correct length so you can do:
        >>
        > a,c,b = fix(1,2)
        > d,e,f = fix(1,2,3,4)
        >>
        >However, the function won't know the length of the left hand side
        >sequence, so it will have to be passed in as an extra parameter or hard
        >coded.
        >>
        >
        Hi Gary,
        >
        thank you for the answer.
        Do you know the "protocol" used by python while unpacking?
        Is it a direct assingnment? Or iterating?
        >
        Both I think, but what do you mean by *direct* assignment?
        It RHS of such an assignment can be any iterable (I think). Lets test:
        (The nice thing about an interactive Python session, it that it's really
        easy to test.)

        >>L = [1,2,3]
        >>a,b,c=L
        >>a,b=L
        Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        ValueError: too many values to unpack
        >>a,b,c,d=L
        Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        ValueError: need more than 3 values to unpack
        >>G = (f for f in [1,2,3]) # A generator expression
        >>a,b,c = G
        >>G = (f for f in [1,2,3]) # A generator expression
        >>a,b = G
        Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        ValueError: too many values to unpack
        >>G = (f for f in [1,2,3]) # A generator expression
        >>a,b,c,d = G
        Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        ValueError: need more than 3 values to unpack


        I'd call that direct assignment with values supplied by any iterable.

        Gary Herron





        Comment

        • Terry Reedy

          #5
          Re: unpacking with default values



          McA wrote:
          Do you know the "protocol" used by python while unpacking?
          Is it a direct assingnment? Or iterating?
          In CPython, at least, both, just as with normal unpack and multiple
          assignment. The iterable is unpacked into pieces by iterating (with
          knowledge of the number of targets and which is the catchall). The
          targets are then directly bound.
          >>from dis import dis
          # first standard assignment
          >>dis(compile(" a,b,c = range(3)", '','single'))
          1 0 LOAD_NAME 0 (range)
          3 LOAD_CONST 0 (3)
          6 CALL_FUNCTION 1
          9 UNPACK_SEQUENCE 3
          12 STORE_NAME 1 (a)
          15 STORE_NAME 2 (b)
          18 STORE_NAME 3 (c)
          21 LOAD_CONST 1 (None)
          24 RETURN_VALUE
          # now starred assignment
          >>dis(compile(" a,b,*c = range(3)", '','single'))
          1 0 LOAD_NAME 0 (range)
          3 LOAD_CONST 0 (3)
          6 CALL_FUNCTION 1
          9 UNPACK_EX 2
          12 STORE_NAME 1 (a)
          15 STORE_NAME 2 (b)
          18 STORE_NAME 3 (c)
          21 LOAD_CONST 1 (None)
          24 RETURN_VALUE

          The only difference is UNPACK_EX (tended) instead of UNPACK_SEQUENCE .
          Tne UNPACK_EX code is not yet in the dis module documentation.
          But a little reverse engineering reveals the parameter meaning:
          a,*b,c and *a,b,c give parameters 257 and 512 instead of 2.
          Separating 2,257,512 into bytes gives 0,2; 1,1; 2,0.
          a,*b and *a,b give 1, 256 or 0,1; 1,0. The two bytes
          are the number of targets after and before the starred target.

          Terry Jan Reedy


          Comment

          Working...