Home > Back-end >  why Python auto cast int to tuple while define variable?
why Python auto cast int to tuple while define variable?

Time:04-28

I'm learning python, use w3schools python tutorial, read about how python "Many Values to Multiple Variables" and confused by the following Casting process.

>>> a=b,c=d = 1,2
>>> print(a,b,c,d)
(1, 2) 1 2 (1, 2)
>>> print(type(a),type(b),type(c),type(d))
<class 'tuple'> <class 'int'> <class 'int'> <class 'tuple'>
>>> x,y,z,t = 1,2,3,4
>>> print(type(x),type(y),type(z),type(t))
<class 'int'> <class 'int'> <class 'int'> <class 'int'>
>>> print(x,y,z,t)
1 2 3 4
>>>

How type of a,d is 'tuple'?

I thought they were 'int' when I study about it.

CodePudding user response:

From the section 7.2 of the language reference, Assignment statements

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

The first assignment statement

a = b, c = d = 1, 2

^     ^    ^    ^
|     |    |     -- expression list
|     |     -- target #3
|      -- target #2
 -- target #1

consists of the expression list 1, 2 (which evaluates to a tuple) and three targets a, b, c, and d, which are assigned in the following order:

a = 1, 2
b, c = 1, 2
d = 1, 2

There is no casting involved. The assignments to a and d assign the tuple directly; the assignment to b and c pairs each target with a corresponding value in the tuple.


Perhaps most notably, it is not like in C where an assignment is considered an expression whose value is the value that was assigned. Something like a = b = c = d in C is equivalent to

/* C with explicit parentheses
 * d is assigned to c, with the value of c = d assigned
 * to b, and the value of b = c = d assigned to a
 */
a = (b = (c = d))

while in Python it is a single statement with the semantics defined above.

A common idiom in C is to use the value of an assignment in a conditional statement, so that you can bind the value being tested to a variable used later in the same statement.

while ((c = foo()) != bar) {
    printf("%s\n", c)
}

Prior to the introduction of the assignment expression in Python, the equivalent required a separate assignment statement before and in the while statement:

c = foo()
while c != bar:
    print(c)
    c = foo()
    

or more idiomatically, an infinite loop with an explicit break condition

while True:
    c = foo()
    if c == bar:
        break
    print(c)

With the assignment expression, you can now embed an assignment into a boolean-valued expression similar to the C example.

while (c := foo()) != bar:
    print(c)

CodePudding user response:

When you do

a=b,c=d = 1,2

following happens

d = 1,2 # now d is 2-tuple
b,c=d # 2-tuple is unpacked, now b is 1 and c is 2
a=b,c # new 2-tuple a is created using b and c, now a is 2-tuple (1,2)

CodePudding user response:

I think it is clearer when you add the () to surround tuples. This

a = (b, c) = d = (1, 2)
print(type(a), type(b), type(c), type(d))
print(a, b, c, d)

is equivalent to

a = b, c = d = 1, 2
print(type(a), type(b), type(c), type(d))
print(a, b, c, d)

So you assign a tuple (1, 2) to three targets a, (b, c) and d from left to right. (b, c) just unpacks the values so b is assigned the first and c assigned the last value of (1, 2). All other variables i. e. a and d just get the tuple (1, 2) assigned.

  • Related