cover_effective_python

【 Effective Python, 2nd Edition 】アンパックのちょっとした使い方 - 1: 一時変数を使わずにスワップする、2: インデックス番号を用いないでネストしている iterable の要素を取り出す - 投稿一覧へ戻る

Tags: Python , iterable , enumerate , unpack , swap , Effective

Published 2020年6月10日16:03 by T.Tsuyoshi

1: 次のようなリストをアルファベット順に並べ替えるとします( sort() を使っちゃダメですよ)。


friends = ['Hana', 'Yuka', 'Nana', 'Saki']



Python に馴染みが薄い方は、次のように一時変数を利用して入れ替えを行うと思います。


def bubble_sort(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i] < a[i - 1]:
temp = a[i]
a[i] = a[i - 1]
a[i - 1] = temp

bubble_sort(friends)
print(friends) # ['Hana', 'Nana', 'Saki', 'Yuka']



しかしアンパックを利用することで、一時変数を利用することなく2つの値をスワップさせることが可能です。


def bubble_sort2(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i] < a[i - 1]:
a[i - 1], a[i] = a[i], a[i - 1]

bubble_sort2(friends)
print(friends) # ['Hana', 'Nana', 'Saki', 'Yuka']



このアンパックを利用した値のスワップでは、
アンパック代入式の右辺 (a[i], a[i - 1]) が先に評価されて内部で自動的に作られる一時変数にセットされ、
続いて左辺の変数へ代入が行われます。そして最後に使用された一時変数は、そっと、消去されます。


2: ネストしている iterable からの要素の取り出しにアンパックを利用することで、コードがインデックス番号だらけになることを防ぐことができ、スッキリします。


次のようなタプルのリストを出力します。


grades = [('Nana', 90), ('Saki', 92), ('Yuka', 82)]



丁寧に記述すると次のようになるでしょうか。


for i in range(len(grades)):
item = grades[i]
name = item[0]
grade = item[1]

print(f"#{i + 1}: {name} は {grade} 点。")

#1: Nana は 90 点。
#2: Saki は 92 点。
#3: Yuka は 82 点。




でも、enumerate() の助けを借りながらアンパックを利用することで、インデックス番号を1つも記述せずに済んじゃいます。


for num, (name, grade) in enumerate(grades, 1):
print(f"#{num}: {name} は {grade} 点。")

#1: Nana は 90 点。
#2: Saki は 92 点。
#3: Yuka は 82 点。

この投稿をメールでシェアする

0 comments

コメントはまだありません。

コメントを追加する(不適切と思われるコメントは削除する場合があります)