[Python-Dev] Extending tuple unpacking

Guido van Rossum guido at python.org
Tue Oct 11 06:55:58 CEST 2005

On 10/10/05, Ron Adam <rrr at ronadam.com> wrote:
> The problem is the '*' means different things depending on where it's
> located.  In a function def, it means to group or to pack, but from the
> calling end it's used to unpack.  I don't expect it to change as it's
> been a part of Python for a long time and as long as it's only used with
> argument passing it's not too difficult to keep straight.
> My concern is if it's used outside of functions, then on the left hand
> side of assignments, it will be used to pack, but if used on the right
> hand side it will be to unpack.  And if it becomes as common place as I
> think it will, it will present confusing uses and or situations where
> you may have to think, "oh yeah, it's umm... unpacking here and umm...
> packing there, but multiplying there".  The point is it could be a
> stumbling block, especially for new Python users.  So I think a certain
> amount of caution should be in order on this item.  At least check that
> it's doesn't cause confusing situations.

This particular concern, I believe, is a fallacy. If you squint the
right way, using *rest for both packing and unpacking is totally
logical. If

    a, b, *rest = (1, 2, 3, 4, 5)

puts 1 into a, 2 into b, and (3, 4, 5) into rest, then it's totally
logical and symmetrical  if after that

    x = a, b, *rest

puts (1, 2, 3, 4, 5) into x.

BTW, what should

    [a, b, *rest] = (1, 2, 3, 4, 5)

do? Should it set rest to (3, 4, 5) or to [3, 4, 5]? Suppose the
latter. Then should we allow

    [*rest] = x

as alternative syntax for

    rest = list(x)

? And then perhaps

    *rest = x

should mean

    rest = tuple(x)

Or should that be disallowed and would we have to write

    *rest, = x

analogous to singleton tuples?

There certainly is a need for doing the same from the end:

    *rest, a, b = (1, 2, 3, 4, 5)

could set rest to (1, 2, 3), a to 4, and b to 5. From there it's a
simple step towards

    a, b, *rest, d, e = (1, 2, 3, 4, 5)


    a, b, rest, d, e = (1, 2, (3,), 4, 5)

and so on. Where does it stop?

BTW, and quite unrelated, I've always felt uncomfortable that you have to write

    f(a, b, foo=1, bar=2, *args, **kwds)

I've always wanted to write that as

    f(a, b, *args, foo=1, bar=2, **kwds)

but the current grammar doesn't allow it.

Still -0 on the whole thing,

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list