10

In python, I can write something like this:

some_list = [(1, 2, 3), (3, 2, 1)]

for i, *args in some_list:
   print(args)

I will get the next output:

[2, 3]
[2, 1]

When we use *args as function arguments, it is unpacked into a tuple.

Why do we receive a list in this situation?

user2390182
  • 72,016
  • 6
  • 67
  • 89
EdiBoba
  • 103
  • 4
  • The [docs](https://docs.python.org/3/reference/expressions.html#expression-lists) don't really specify what unpacking should return other than a sequence - " which are included in the new tuple, list, or set, at the site of the unpacking." – Sayse Oct 29 '21 at 07:41
  • @Sayse If you look at the *correct* places in the docs, you'll find they say list and tuple, respectively. – Kelly Bundy Oct 29 '21 at 08:14
  • @KellyBundy - What are the "correct" places? That sounds like it'd make a decent answer to this question. – Sayse Oct 29 '21 at 08:17
  • @Sayse Assignment and function definition. Not expressions. Neither are expressions. Not posting as answer because the question is "why" (and that already has been answered). – Kelly Bundy Oct 29 '21 at 08:19
  • @Sayse Err, well, a function *call* of course *is* an expression, and the doc of that says tuple as well. – Kelly Bundy Oct 29 '21 at 08:28
  • 1
    @EdiBoba You say "`*args` as function arguments" and "unpacked" but appear to mean function *parameter* and "packed". – Kelly Bundy Oct 29 '21 at 08:32
  • Related: [Why does splatting create a tuple on the rhs but a list on the lhs?](https://stackoverflow.com/q/56237733/5349916) – MisterMiyagi Oct 29 '21 at 08:33

2 Answers2

10

It is just a design decision. Making it a tuple was debated in the PEP 3132, but rejected on usability grounds:

Make the starred target a tuple instead of a list. This would be consistent with a function's *args, but make further processing of the result harder.

Simlarly, making it of the same type as the iterable on the rhs of the assignment, was rejected:

Try to give the starred target the same type as the source iterable, for example, b in a, *b = 'hello' would be assigned the string 'ello'. This may seem nice, but is impossible to get right consistently with all iterables.

The very example of yours is listed in the same PEP under specification.

Some reasoning is found in the mailing list of that debate.

When dealing with an iterator, you don't know the length in advance, so the only way to get a tuple would be to produce a list first and then create a tuple from it.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Wasn't my downvote but I guess it would be nice to find an answer to where unpacking would return each difference sequence type but not sure without digging deep into the python github you'd find that out – Sayse Oct 29 '21 at 07:50
  • 1
    @Sayse. The prior bullet in the same list addresses that – Mad Physicist Oct 29 '21 at 07:57
-2

Check this one - https://mail.python.org/pipermail/python-3000/2007-May/007312.html

it says "When dealing with an iterator, you don't know the length in advance, so the only way to get a tuple would be to produce a list first and then create a tuple from it"

Sachin84
  • 47
  • 8
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34354018) – KingOtto May 12 '23 at 09:52
  • 1
    The exact same link and quote has already been provided by [the accepted answer](https://stackoverflow.com/a/69765266/5349916) more than a year ago. What does this answer add? – MisterMiyagi May 12 '23 at 10:44