Why Does Adding a Trailing Comma After a Variable Name Make It a Tuple

Why does adding a trailing comma after an expression create a tuple?

It is the commas, not the parentheses, which are significant. The Python tutorial says:

A tuple consists of a number of values separated by commas

Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.

See the Python Tutorial section on Tuples and Sequences

What is the syntax rule for having trailing commas in tuple definitions?

In all cases except the empty tuple the comma is the important thing. Parentheses are only required when required for other syntactic reasons: to distinguish a tuple from a set of function arguments, operator precedence, or to allow line breaks.

The trailing comma for tuples, lists, or function arguments is good style especially when you have a long initialisation that is split over multiple lines. If you always include a trailing comma then you won't add another line to the end expecting to add another element and instead just creating a valid expression:

a = [
"a",
"b"
"c"
]

Assuming that started as a 2 element list that was later extended it has gone wrong in a perhaps not immediately obvious way. Always include the trailing comma and you avoid that trap.

Unintentional trailing comma that creates a tuple

pylintalready detects this as a problem (as of version 1.7).

For example, here's my tuple.py:

"""Module docstring to satisfy pylint"""

def main():
"""The main function"""
thing = 1,
print(type(thing))

if __name__ == "__main__":
main()
$ pylint tuple.py
No config file found, using default configuration
************* Module tuple
R: 5, 0: Disallow trailing comma tuple (trailing-comma-tuple)

------------------------------------------------------------------
Your code has been rated at 8.00/10 (previous run: 8.00/10, +0.00)

$ pylint --help-msg trailing-comma-tuple
No config file found, using default configuration
:trailing-comma-tuple (R1707): *Disallow trailing comma tuple*
In Python, a tuple is actually created by the comma symbol, not by the
parentheses. Unfortunately, one can actually create a tuple by misplacing a
trailing comma, which can lead to potential weird bugs in your code. You
should always use parentheses explicitly for creating a tuple. This message
belongs to the refactoring checker. It can't be emitted when using Python <
3.0.

Why is a trailing comma needed here to pass a list in an *args parameter?

Because the comma makes the tuple, or so the saying goes.

(1) is just grouping parens, but (1, ) is a tuple with one int. In this case under the hood the thread initializer is unpacking args, so without the comma it's unpacking test list, basically test_func(*test_list) but with the comma it unpacks the tuple, and everything works.

x, = ... - is this trailing comma the comma operator?

ax.plot() returns a tuple with one element. By adding the comma to the assignment target list, you ask Python to unpack the return value and assign it to each variable named to the left in turn.

Most often, you see this being applied for functions with more than one return value:

base, ext = os.path.splitext(filename)

The left-hand side can, however, contain any number of elements, and provided it is a tuple or list of variables the unpacking will take place.

In Python, it's the comma that makes something a tuple:

>>> 1
1
>>> 1,
(1,)

The parenthesis are optional in most locations. You could rewrite the original code with parenthesis without changing the meaning:

(line,) = ax.plot(x, np.sin(x))

Or you could use list syntax too:

[line] = ax.plot(x, np.sin(x))

Or, you could recast it to lines that do not use tuple unpacking:

line = ax.plot(x, np.sin(x))[0]

or

lines = ax.plot(x, np.sin(x))

def animate(i):
lines[0].set_ydata(np.sin(x+i/10.0)) # update the data
return lines

#Init only required for blitting to give a clean slate.
def init():
lines[0].set_ydata(np.ma.array(x, mask=True))
return lines

For full details on how assignments work with respect to unpacking, see the Assignment Statements documentation.

Why does adding a trailing comma after an expression create a tuple?

It is the commas, not the parentheses, which are significant. The Python tutorial says:

A tuple consists of a number of values separated by commas

Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.

See the Python Tutorial section on Tuples and Sequences

Why does a comma appear in the output after the string is used in unpacking in a function?

This behavior is expected: the tuples you're passing into the function in the bottom two examples represent the first argument in the variadic *args tuple (the name doesn't matter, you used *n). The purpose of *args is to create a tuple containing all of the non-keyword arguments passed to a function.

Creating a single-element tuple always prints with a trailing comma to distinguish it as a tuple. In the bottom two cases, you have a single-element args tuple with a 4 or 2 element tuple as its lone element.

Your sentence "comma appears after tuple when string is added to the argument" is incorrect--you removed the unpacking operator * from the call which no longer flattens the tuple into variable arguments, so the string has nothing to do with it. You'd still get the hanging comma even if you passed a number as the lone argument:

>>> def f(*args): print(args)
...
>>> f(1)
(1,) # `args` tuple contains one number
>>> f(1, 2)
(1, 2) # `args` tuple contains two numbers
>>> f((1, 2))
((1, 2),) # two-element tuple `(1, 2)` inside single-element `args` tuple
>>> f((1,))
((1,),) # single-element tuple `(1,)` inside single-element `args` tuple
>>> f(*(1,)) # unpack the tuple in the caller, same as `f(1)`
(1,)
>>> f(*(1,2)) # as above but with 2 elements
(1, 2)
>>> f((1)) # without the trailing comma, `(1)` resolves to `1` and is not a tuple
(1,)


Related Topics



Leave a reply



Submit