Python style advice

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Nick Craig-Wood

    Python style advice

    Python newbie advice needed!

    I'm tring to write what I would have expressed in Perl as

    my ($a, $b, $c) = @array;

    This is very similar to the python statement

    a, b, c = array

    BUT, the Python will throw an exception if array isn't exactly 3
    elements long, wheras the Perl will work for any length of @array,
    either throwing away excess elements or setting the variables to
    undef, ie like this

    if len(array) >= 1:
    a = array[0]
    else:
    a = None
    if len(array) >= 2:
    b = array[1]
    else:
    b = None
    if len(array) >= 3:
    c = array[2]
    else:
    c = None

    This works if array has >= 3 elements

    a, b, c = array[:3]

    And this works however many elements array has

    a, b, c = (array + 3*[None])[:3]

    but it doesn't seem very Pythonic - is there a better way?

    --
    Nick Craig-Wood
    ncw@axis.demon. co.uk
  • Wayne Folta

    #2
    Re: Python style advice

    In the specific case where you're trying to map a variable-length
    argument list to local variables in a function, you can do the more
    Pythonic:

    def myfunc (a = None, b = None, c = None)

    I'd say the answer is similar for other tasks. There's probably a
    Pythonic way to do the overall task as opposed to a
    statement-by-statement translation.
    [color=blue]
    > I'm tring to write what I would have expressed in Perl as
    >
    > my ($a, $b, $c) = @array;
    >
    > This is very similar to the python statement
    >
    > a, b, c = array
    >
    > BUT, the Python will throw an exception if array isn't exactly 3
    > elements long, wheras the Perl will work for any length of @array,
    > either throwing away excess elements or setting the variables to
    > undef, ie like this
    >
    > if len(array) >= 1:
    > a = array[0]
    > else:
    > a = None
    > if len(array) >= 2:
    > b = array[1]
    > else:
    > b = None
    > if len(array) >= 3:
    > c = array[2]
    > else:
    > c = None
    >
    > This works if array has >= 3 elements
    >
    > a, b, c = array[:3]
    >
    > And this works however many elements array has
    >
    > a, b, c = (array + 3*[None])[:3]
    >
    > but it doesn't seem very Pythonic - is there a better way?
    >
    > --
    > Nick Craig-Wood
    > ncw@axis.demon. co.uk
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >[/color]


    Comment

    • Terry Reedy

      #3
      Re: Python style advice


      "Nick Craig-Wood" <ncw@axis.demon .co.uk> wrote in message
      news:slrnc2enr8 .bmp.ncw@irishs ea.home.craig-wood.com...[color=blue]
      > Python newbie advice needed!
      >
      > I'm tring to write what I would have expressed in Perl as
      >
      > my ($a, $b, $c) = @array;
      >
      > This is very similar to the python statement
      >
      > a, b, c = array
      >
      > BUT, the Python will throw an exception if array isn't exactly 3 elements[/color]
      long,

      This is an intentional feature. Mismatches are often bugs.
      [color=blue]
      > wheras the Perl will work for any length of @array,
      > either throwing away excess elements or setting the variables to
      > undef, ie like this[/color]

      Guido's philosophy is that the interpreter should resist guessing like this
      when code is at least half likely to be buggy.
      [color=blue]
      > And this works however many elements array has
      >
      > a, b, c = (array + 3*[None])[:3]
      >
      > but it doesn't seem very Pythonic - is there a better way?[/color]

      Being explicitly generic is Pythonic to me. Or do something like

      a=b=c=None
      try: c=array[2]
      try: b=array[1]
      try: a=array[1]
      except: pass
      except: pass
      except: pass

      but I prefer the one liner here. It is easier to extend to more names.

      Terry J. Reedy






      Comment

      • Nick Craig-Wood

        #4
        Re: Python style advice

        Wayne Folta <wfolta@netmail .to> wrote:[color=blue]
        > In the specific case where you're trying to map a variable-length
        > argument list to local variables in a function, you can do the more
        > Pythonic:
        >
        > def myfunc (a = None, b = None, c = None)[/color]

        Interesting... I was thinking in particular of sys.argv with this
        example, but the above gave me the idea below which would work quite
        well (imagine sys.argv in place of L below)
        [color=blue][color=green][color=darkred]
        >>> def f(a=None,b=None ,c=None,*extra) : print a,b,c[/color][/color][/color]
        ....[color=blue][color=green][color=darkred]
        >>> L=[]; apply(f,L)[/color][/color][/color]
        None None None[color=blue][color=green][color=darkred]
        >>> L=[1]; apply(f,L)[/color][/color][/color]
        1 None None[color=blue][color=green][color=darkred]
        >>> L=[1,2]; apply(f,L)[/color][/color][/color]
        1 2 None[color=blue][color=green][color=darkred]
        >>> L=[1,2,3]; apply(f,L)[/color][/color][/color]
        1 2 3[color=blue][color=green][color=darkred]
        >>> L=[1,2,3,4]; apply(f,L)[/color][/color][/color]
        1 2 3[color=blue][color=green][color=darkred]
        >>> L=[1,2,3,4,5]; apply(f,L)[/color][/color][/color]
        1 2 3

        --
        Nick Craig-Wood
        ncw@axis.demon. co.uk

        Comment

        • Terry Reedy

          #5
          Re: Python style advice


          "Nick Craig-Wood" <ncw@axis.demon .co.uk> wrote in message
          news:slrnc2h9id .um.ncw@irishse a.home.craig-wood.com...[color=blue][color=green]
          > > def myfunc (a = None, b = None, c = None)[/color][/color]
          [color=blue][color=green][color=darkred]
          > >>> def f(a=None,b=None ,c=None,*extra) : print a,b,c[/color][/color][/color]
          ...[color=blue][color=green][color=darkred]
          > >>> L=[]; apply(f,L)[/color][/color][/color]

          You can now write 'apply(f,L)' as f(*L) and be future-proof in case apply
          disappears

          tjr




          Comment

          Working...