Pythonの分割代入について

JavaScriptなどでおなじみの分割代入(Destructuring assignment)構文ですが、Pythonにもあります。

x, y = (2, 3)
print(f"x = {x} , y = {y}")
# x = 2 , y = 3

上例のようにtupleを分割代入する場合、「tupleのunpack」とも呼ばれます。この逆変換は、「tupleへのpack」とも呼ばれます。(次例)

x = 2
y = 3
z = (x, y)
print(z)
# (2, 3)

この分割代入の構文で右辺にこれるのは、sequenceです。例えば、文字列(str)は、iterableであり、sequenceとみなされるので、次のようにunpackできます。

a, b, c = "ABC"
print(b)
# B

同様に、rangeオブジェクトもsequenceなので、次のようにunpackできます。

a, b, c = range(3)
print(b)
# 1

右辺のsequenceの要素数と左辺に書かれた変数の数が一致しないと実行時のエラーになります。

a,b,c = range(10)
print(b)
# ValueError : too many values to unpack (expected 3)

変数の数が足りないとき、アスタリスク * をつけて、残りの要素をlistとして代入することができます。

a, b, *c = range(10)
print(c)
# [2, 3, 4, 5, 6, 7, 8, 9]
# 残りの要素がlist化されて代入されます。

a, b, *c = (0, 1, 2, 3, 4)
print(a)
print(b)
print(c)
# 0
# 1
# [2, 3, 4]

a, *b, c = (0, 1, 2, 3, 4)
print(a)
print(b)
print(c)
# 0
# [1, 2, 3]
# 4

*a, b, c = (0, 1, 2, 3, 4)
print(a)
print(b)
print(c)
# [0, 1, 2]
# 3
# 4

a, b, *c = (0, 1, 2)

print(a)
print(b)
print(c)
# 0
# 1
# [2]
// 要素が1つでも*をつけたものはlistになるので注意。

a,b,*c = range(2)
print(c)
# []
// *をつけた時に、右辺に対応する要素がない場合は、空のlistになる。

入れ子になったtupleからの代入。

a, b, c = (0, 1, (2, 3, 4))
print(a)
print(b)
print(c)
# 0
# 1
# (2, 3, 4)

左辺がtupleになっている代入。

a, b, (c,d,e) = (0, 1, (2, 3, 4))
print(a)
print(b)
print(c)
print(d)
print(e)
# 0
# 1
# 2
# 3
# 4

入れ子になったlistからの代入、左辺がlistになっている代入。

a,b,c = [0, 1, [2, 3, 4]]
print(a)
print(b)
print(c)
# 0
# 1
# [2, 3, 4]

a, b, [c,d,e] = (0, 1, (2, 3, 4))
print(a)
print(b)
print(c)
print(d)
print(e)
# 0
# 1
# 2
# 3
# 4

次のような代入もできる。

t = [1, 2]
a, b = t[0], t[1]
print(a)
print(b)
print(type((t[0],t[1])))
# 1
# 2
# <class 'tuple'>
// t[0],t[1] はtupleであり、これはtupleからの分割代入である。

(Visited 10 times, 1 visits today)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です