[Tutor] *args consumption

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Mar 10 20:37:57 CET 2006


> Am I missing some other usage where you wouldn't want to unpack the
> *arg? If not, would the following "behind the scenes" behavior be
> possible/preferred?
>
> ###
> def foo(*arg):
>     pass
> ###
>
> automatically does this
>
> ###
> def foo(*arg):
>     if len(arg) == 1:
>         arg = arg[0]
>     pass
> ###


Yes: what if we're passing foo() some mixed data?  This might not be as
weird as it might sound: imagine that a cartegian point [x, y] is
represented either as a point:

    [x, y]

or as a single x coordinate number x where the y coordinate is assumed to
be zero.

    x

Our list would then contain a mix of data.  For example, a list with the
points (4, 3) and (5, 0) and (2, 9) could be represented as:

    [[4, 3], 5, [2, 9]]


And even though this looks a little weird, this still works perfectly ok,
because we can write functions to reliably get the x,y coordinates of this
mixed representation:

##########################
def getX(point):
    if type(point) == int:
        return point
    else:
        return point[0]

def getY(point):
    if type(point) == int:
        return 0
    else:
        return point[1]
##########################



Anyway, ok, so we have points.  What's more natural than drawing them and
playing connect the dots?  *grin*

#################################################################
def playConnectTheDots(*points):
    """Draws all the points given and connects them together with
    lines."""
    # ... fill me in
#################################################################


But if we pass playConnectTheDots() with a single point, we want the
function not to automatically unpack the argument as if it were something
else: it would be a lossy kind of implicit transformation.


If the case of len(points) == 1 is treated as a special case, that would
make the logic turn into... well, I don't know, it would be ambiguous!

>From the example above, if we did feed it:

    playConnectTheDots([[4, 3]])      ## Draw the point (4, 3)

vs:

    playConnectTheDots([4, 3])        ## Draw between (4, 0) and (3, 0)

then imagine what would happen if Python did the kind of automatic
unwrapping you're thinking of.  How would it tell the difference between
these two different cases?


So making a special case for the singular list probably won't be as nice
as we might expect.  It's often better to treat them all consistantly.
Lists with one element aren't bad!  *grin*



More information about the Tutor mailing list