I was looking through an interesting example script I found (at this site, last example line 124), and I\'m struggling to understand what the comma after particles
It is needed to unpack the 1-tuple (or any other length-1 sequence). Example:
>>> a,b = (1,2)
>>> print a
1
>>> print b
2
>>> c, = (3,)
>>> print c
3
>>> d = (4,)
>>> print d
(4,)
Notice the difference between c and d.
Note that:
a, = (1,2)
fails because you need the same number of items on the left side as the iterable on the right contains. Python 3.x alleviates this somewhat:
Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:09:56)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a,*rest = (1,2,3)
>>> a
1
>>> rest
[2, 3]
For the sake of being educational, I will make this a bit long.
In Python, tuples are delimited with parentheses, e.g.: (1, 2, 3)
.
Unfortunately, a tuple consisting of just a single element like 1
would be ambiguous (from a parsing point of view) if specified as simply (1)
, since that could mean the integer one inside parentheses in the middle of an expression.
To overcome that, you can specify a tuple with just one element with the element just followed by a single comma, as in (1,)
. (Just to make it clear, the comma is what makes it a tuple, not the parentheses, which we can omit when things are not ambiguous, and which is what I do below). That is unambiguously the tuple containing a sole single 1
as its element, as is illustrated in the following example:
>>> a = (1)
>>> a
1
>>> b = (1,)
>>> b
(1,)
>>> b[0]
1
>>> c, = b
>>> c
1
>>>
What you mentioned is a way to "unpack" the tuple, that is, to access a specific element of the tuple. One alternative to the syntax that you used is to index the element in the tuple by a 0, like my b[0]
in the example above.
For tuples with more than one element, you can unpack them just by specifying an attribution with the same number of elements that the tuple has:
>>> x, y = (1, 2)
>>> x
1
>>> y
2
If you don't use the same number of elements when unpacking a tuple, you will get an exception being thrown:
>>> z, = (1, 2, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>>
In your "example" of why the unpacking theory "fails", you can simply use:
>>> a, _ = [2, 3]
>>> a
2
Note the _
there, which is a usual variable used in Python for the meaning of "we don't care".
As an addendum, note that in a, _ = [2,3]
, you are implicitly creating a tuple, which is an immutable type, from a list, which is a mutable type. (Note that this "implicit" conversion is conceptual, as the Python interpreter may not generate a BUILD_TUPLE
instruction in the bytecode). Note the subtleties in the following attributions:
>>> a, b = [2, 3]
>>> a
2
>>> b
3
>>> a, b
(2, 3)
>>> c, d = tuple([2, 3])
>>> c
2
>>> d
3
>>> e = [2, 3]
>>> type(e)
<type 'list'>
>>> type((a, b))
<type 'tuple'>
Have a look at what plot
call returns. In your case it's a list with one element:
>>> import matplotlib.pyplot as plt
>>> ax = plt.gca()
>>> ax.plot([], [], 'bo', ms=6)
[<matplotlib.lines.Line2D object at 0x353d6d0>]
Now it would more useful in this case to have a handle on the actual Line2D object, using unpacking with h, = ax.plot(...)
rather than a spurious container around it as you would get with
h = ax.plot([], [], 'bo', ms=6)
The latter would require you an extra step later on e.g.
h[0].set_data(...)
Return value of plot is always a list, because sometimes it needs to return more than one line object. It makes more sense to return even single lines inside a list, so that client code doesn't have to handle each case in a different way.
The reason your unpacking a, = [2,3]
fails is that there are 2 things to unpack on the right side, and only one variable. You would need to use a,b = [2,3]
to unpack that.