講義でタプルについて触れたのだが中々面白そうなことができると発見したので備忘録のために。
Select by item number
例えば以下の様なコードを書いたとする。
>>> x = (1, 7, 5)
>>> from operator import getitem
>>> print(getitem(x, 1), getitem(x, 2))
7 5
>>> print(x.__getitem__(1), x.__getitem__(2))
7 5
タプルに入っている要素を色んなやり方で取ってこれる。個人的には一番シンプルな[index]
を使っていたのだが、pythonのmethod
という機能を使えばgetitem
を持ってきていじったりすることができると。これはnotation
(add
, len
, ==
)とは機能は同じだが実装の仕方が若干異なる。どうやら作った人の自己満でこういうのが生まれたとか聞いたような。
Select by "unpacking" (=deconstruction of tuples)
ここからが本題。タプルが複数ネストされているコードを見かけた時割りと直感的に要素を取ってくることが出来る。これをDeconstruction of tuplesと呼ぶらしい。今風に言えばunpacking。
>>> x = (1, (2,3), 5)
>>> a,b,c = x
>>> print(b,c)
(2, 3) 5
>>> d, (e,f),g = x
>>> print(e,g)
2 5
>>> x = d, (e,f),g
>>> print(e,g)
2 5
>>> x
(1, (2, 3), 5)
タプルの一個目のネストに入ったらその中のタプルは中身を見ずに一つの要素としてみなす、という考え方。だからa = 1, b = (2, 3), c = 5
になるわけだ。これを使って逆にx
の中身を新しく用意した変数にアサインさせてコピーを作ることも出来る。素晴らしい。
これを応用すると以下の様な関数を作れるということを発見した。
#!/usr/bin/python
# function that returns a tuple
def foo():
return ('w', 'x', ('y', 'z'))
# function that "deconstructs" a tuple argument
def bar(x, (y, z)):
assert x == 'd'
assert y == 'e'
assert z == 'f'
if __name__ == '__main__':
# make a nested tuple
t = ('a', 'b', ('c', 'd'))
# use tuple assignment
(m, n, (o, p)) = t
assert m == 'a'
assert n == 'b'
assert o == 'c'
assert p == 'd'
# function that returns a tuple
(m, n, (o, p)) = foo()
assert m == 'w'
assert n == 'x'
assert o == 'y'
assert p == 'z'
# function that "deconstructs" a tuple argument
bar('d', ('e', 'f'))
これは関数のreturned valueに予めタプルを入れておいてそれをイジって新しい関数にアサインするという方法だ。=
ってこんな細かいところにまで手が届いているんだな。