On Tue, Oct 22, 2013 at 3:20 PM, Key, Gregory E (E S SF RNA FSF 1 C) <gregory....@siemens.com> wrote: > I understand that a comma in Python is a separator and not an operator. In
The comma operator creates a tuple. It has low precedence, so you usually need parentheses. But sometimes the parentheses are redundant such as with a return statement like `return (x, y, z)` vs `return x, y, z`, or on the right-hand side of an assignment: >>> y = 1, 2, 3 >>> y (1, 2, 3) > some of the MatPlotLib examples I see code like this: > > line1, = ax1.plot(t, y1, lw=2, color='red', label='1 HZ') > > What does the comma do in an assignment statement? For an assignment target list, CPython doesn't actually create a tuple. It's a notational tuple used by the compiler. It's present in the abstract syntax tree (creating an AST is an intermediate step in the compilation process); however, the final bytecode does sequence unpacking directly to the target names. Here's the AST for `y, = x`: >>> print ast.dump(ast.parse('y, = x').body[0]) Assign(targets=[Tuple(elts=[Name(id='y', ctx=Store())], ctx=Store())], value=Name(id='x', ctx=Load())) The AST Tuple in the assignment consists of one item, a Name with a Store context. In this case, the compiler generates bytecode to unpack a length 1 sequence and store the item to the name "y". In practice this is pretty simple and intuitive: >>> y, = [1] >>> y 1 >>> x, y, z = 1, 2, 3 >>> x, y, z (1, 2, 3) You can use compile() and dis to see the bytecode itself: >>> dis.dis(compile('y, = x', '', 'exec')) 1 0 LOAD_NAME 0 (x) 3 UNPACK_SEQUENCE 1 6 STORE_NAME 1 (y) 9 LOAD_CONST 0 (None) 12 RETURN_VALUE The argument in UNPACK_SEQUENCE(1) is the number of items to unpack to the frame's stack. For stack-based operations, think of using an RPN calculator. An operator -- in this case a bytecode instruction -- pops its operands off the stack and then pushes the result back on in their place. The more complex the expression, the bigger the stack needs to grow (think of a stack of plates) in order to hold temporary results. Unpacking can also handle more complex structures such as `t, (x, y) = z`: >>> z = [1, [2, 3]] >>> t, (x, y) = z >>> t, x, y (1, 2, 3) If you prefer, you can use square brackets on the left-hand side. The compiled bytecode is the same, whether the left-hand side has Tuple or List types in the AST: >>> [t, [x, y]] = z >>> t, x, y (1, 2, 3) Bytecode comparison: >>> dis.dis(compile('t, (x, y) = z', '', 'exec')) 1 0 LOAD_NAME 0 (z) 3 UNPACK_SEQUENCE 2 6 STORE_NAME 1 (t) 9 UNPACK_SEQUENCE 2 12 STORE_NAME 2 (x) 15 STORE_NAME 3 (y) 18 LOAD_CONST 0 (None) 21 RETURN_VALUE >>> dis.dis(compile('[t, [x, y]] = z', '', 'exec')) 1 0 LOAD_NAME 0 (z) 3 UNPACK_SEQUENCE 2 6 STORE_NAME 1 (t) 9 UNPACK_SEQUENCE 2 12 STORE_NAME 2 (x) 15 STORE_NAME 3 (y) 18 LOAD_CONST 0 (None) 21 RETURN_VALUE After the first unpack, item 0 is popped off the stack and stored to t. Next item 1 (a length 2 sequence) is popped, unpacked, and stored to x and y. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor