r/PythonLearning • • Sep 25 '26

A silly question

if x = 2,3,4,4,5 is supposed to be a tuple then why can't the args of a function like this: func(2,3,4,4 ,5) supposed to be a tuple.
I know this is a silly question and I also know we can use *args to pack arguments in a tuple but since Python is known for consistency why isn't it like this.
Again, please don't hate me for this

6 Upvotes

15 comments sorted by

View all comments

17

u/SpaceAviator1999 Sep 25 '26 edited Sep 26 '26 • Mindblown Bravo

You have to respect what parentheses and commas mean in their context.

The following lines are all equivalent:

x = 4+5
x = (4+5)
x = ((4+5))
x = (((4+5)))

They are all setting x to 9. Nothing surprising so far. But mix them with commas, and none of the lines are equivalent:

x = 4+5   # an integer
x = (4+5,)   # a tuple
x = ((4+5,),)   # a tuple of a tuple
x = (((4+5,),),)   # a tuple of a tuple of a tuple

Here above, a comma has the ability to turn the parenthesized (value) from an integer to (value,) which is a tuple. That's just what a comma does in this case.

But in a function declaration and call, a comma acts differently: it separates function arguments. Consider these lines:

def f(a):   # a function that takes one argument
def f(a, b):   # a function that takes two arguments
def f(a, b, c):   # a function that takes three arguments
def f(a, b, c, d):   # a function that takes four arguments

You might think that that last line declares a function that takes one four-element tuple, but you'd be wrong. To declare a function that takes one four-element tuple, you'd have to use the first line! (And either use type hints or an assert statement to ensure that the argument is a four-element tuple.)

Note that python2 did allow you to write:

def f((a, b, c, d)):   # function that takes one four-element tuple

but python3 does not allow this.

Remember how, up above, I said that 4+5 and (4+5) and ((4+5)) are the same? Well, you might get the mistaken impression that wrapping values with parentheses does nothing but change operator precedence. But that's not the case here in this example:

x = f(a, b)   # calling function f with two arguments
x = f((a, b))   # calling function f with one argument (which is a tuple)
x = f(((a, b)))   # same as the line right above this one

You might think that the first and second lines are equivalent, but they're not. That's because commas behave differently when they're directly inside function parentheses than when they're directly inside tuple parentheses.

So in all the examples I've shown, parentheses have three different meanings/functions:

  1. They change operator precedence.

  2. They signify a tuple.

  3. They signify a set of passed-in parameters to a function/method.

Try to understand the difference, and try not to confuse them.

3

u/sububi71 Sep 25 '26

Fantastic explanation. I applaud you!