tags:

views:

149

answers:

5

Consider this function getPos() which returns a tuple. What is the difference between the two following assignments? Somewhere I saw an example where the first assignment was used but when I just tried the second one, I was surprised it also worked. So, is there really a difference, or does Python just figure out that the left-hand part should be a tuple?

def getPos():
  return (1, 1)

(x, y) = getPos() # First assignment
x, y   = getPos() # Second assignment
+5  A: 

Yes, it's called tuple unpacking:

"Tuple unpacking requires that the list of variables on the left has the same number of elements as the length of the tuple." - Guido Van Rossum

"When you use tuples or lists on the left side of the =, Python pairs objects on the right side with targets on the left and assigns them from left to right." - Lutz and Ascher

Skilldrick
+3  A: 

yes, and it works also on list

>>> x,y,z = range(3)
>>> print x, y, z
0 1 2
>>> 
Ant
+8  A: 

Read about tuples:

A tuple consists of a number of values separated by commas (...)

So parenthesis does not make a tuple a tuple. The commas do it.

Parenthesis are only needed if you have weird nested structures:

x, (y, (w, z)), r
Felix Kling
Also to make a single value tuple: `(x,)`
fortran
Yes, although the terms "tuple packing" and "tuple unpacking" suggest it's not quite as straightforward as comma-separated lists always being literal tuples.
Skilldrick
For example, `type(1, 2, 3)` doesn't return `tuple`.
Skilldrick
Thanks for the answer. So, which of the above assignments is the most preferred / most common way?
Helper Method
@Skilldrick: Sure but this is because `type` takes also three arguments: `type(name, bases, dict)`. Clearly, you have to use parenthesis if you want to pass a tuple to a function. Otherwise they are function arguments.
Felix Kling
@Helper Method: Whatever you feel more comfortable with. Parenthesis often make it clearer that one es dealing with a tuple, but in your example it really makes no difference.
Felix Kling
@Felix Yes, but I think it's safer to say that comma separated values are packed/unpacked into tuples during assignment, rather than saying that comma separated values *are* tuples.
Skilldrick
@Skilldrick: Ok, I got your point.
Felix Kling
@fortran: Actually, you don't need parenthesis for this, but I guess it is good practice, to make it clearer.
Felix Kling
@Felix - Thanks. I do think the docs are inconsistent, because "Tuple unpacking requires that the list of variables on the left has the same number of elements as the length of the tuple" implies that a list of variables is not a tuple, whereas "A tuple consists of a number of values separated by commas" implies the opposite. I'm not enough of an expert to know which is true - where's Martelli when you need him? :)
Skilldrick
Here's a common use case for parentheses: `for index, (x, y) in enumerate(points):`...
FogleBird
@FogleBird: Exactly, because in this case the "outer" object is a tuple that contains an integer and another tuple, namely the `x,y` pair...
Felix Kling
+1  A: 

There's no difference.

fortran
+4  A: 

There is no difference:

>>> import dis
>>> dis.dis(compile("a,b = expr()", "", "single"))
  1           0 LOAD_NAME                0 (expr)
              3 CALL_FUNCTION            0
              6 UNPACK_SEQUENCE          2
              9 STORE_NAME               1 (a)
             12 STORE_NAME               2 (b)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        
>>> dis.dis(compile("(a,b) = expr()", "", "single"))
  1           0 LOAD_NAME                0 (expr)
              3 CALL_FUNCTION            0
              6 UNPACK_SEQUENCE          2
              9 STORE_NAME               1 (a)
             12 STORE_NAME               2 (b)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        

Both a, b and (a, b) specify a tuple, and you need a tuple in the LHS (left hand side) for tuple unpacking :)

ΤΖΩΤΖΙΟΥ