How Does Python's Comma Operator Work During Assignment

How does Python's comma operator work during assignment?

All the expressions to the right of the assignment operator are evaluated before any of the assignments are made.

From the Python tutorial: First steps towards programming:

The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.

Emphasis mine.

Your code is functionally equivalent to the following:

a, b = 5 + 4, 5
print a, b

What is the comma doing in this assignment?

Python allows you to assign more than one variable at once, like this:

a, b = 1, 2

The way this works is by treating the left hand side of the assignment a, b as a tuple, and assigning each element in the tuple 1, 2 on the right hand side to it.

Since tuples can have just one element, the following also works:

a, = 1,

The right hand side of a multiple assignment doesn't have to be a tuple. Any iterable will do, as long as the number of elements on each side is the same:

a, b, c = "three little pigs".split()

If the number of elements doesn't match:

a, b, c = "oh", "no"

... you get a ValueError:

ValueError: not enough values to unpack (expected 3, got 2)

Putting all of the above together, then, your function:

def find_project(project_name):    
projects = get_projects()
try:
match, = (proj for proj in projects if proj["name"].strip() == project_name)
return match
except ValueError:
return None

... iterates over the generator expression

(proj for proj in projects if proj["name"].strip() == project_name)

... and if the result has one element, assigns that element to match. If not, ValueError is raised (and caught by the except clause), no assignment happens, and None is returned .

Two things to note:

  1. The comma , is easy to miss when reading code. An alternative would be to use list syntax on the left hand side:

    [match] = (proj for proj in projects if proj["name"].strip() == project_name)

    ... which has the same effect.

  2. When the right hand side is a generator expression (or some other kind of iterator), you can use next() with a default value instead:

    def find_project(project_name):    
    projects = get_projects()
    it = (proj for proj in projects if proj["name"].strip() == project_name)
    return next(it, None)

    ... which is shorter and more readable.

meaning of comma operator in python

x0, sigma = 0, 0.1 is syntactic sugar. Some stuff is happening behind the scenes:

  • 0, 0.1 implicitly creates a tuple of two elements.

  • x0, sigma = unpacks that tuple into those two variables.

If you look at the docs for numpy.histogram, you see that it returns these two things:

hist : array
The values of the histogram. See density and weights for a description of the possible semantics.

bin_edges : array of dtype float
Return the bin edges (length(hist)+1).

Your y, xe = ... unpacks the tuple of the two returned arrays respectively. That is why your y is assigned to a numpy int64 array and your xe assigned to a numpy float array.

Is this comma-separated Python line creating a tuple?

nums[start], nums[end], end = nums[end], nums[start], end - 1 The right side of the assignment creates indeed a tuple. The left side unpacks the tuples straightaway. Perhaps its easier to understand if you would split it up into two assignments:

# create a tuple: (nums[end], nums[start], end - 1)
atuple = nums[end], nums[start], end - 1

# unpack the tuple into: nums[start], nums[end], end
nums[start], nums[end], end = atuple

# To make it more clear, here's an example using basic values
another_tuple = 1, 2, 3

# unpack the tuple -> a = 1, b = 2, c = 3
a, b, c = another_tuple

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.

What does the comma after the target name in this assignment statement do?

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]

How does comma operator work during assignment?

Yes, that's exactly it: the compiler takes the last value. That's the comma operator, and it evaluates its operands left-to-right and returns the rightmost one. It also resolves left-to-right. Why anyone would write code like that, I have no idea :)

So int b = (1, 2, 3) is equivalent to int b = 3. It's not a primitive list of any kind, and the comma operator , is mostly used to evaluate multiple commands in the context of one expression, like a += 5, b += 4, c += 3, d += 2, e += 1, f for example.



Related Topics



Leave a reply



Submit