python_coding_challenge

【Python 雑談・雑学 + coding challenge】シーケンス ( sequence ) における インデックス ( index ) を使った要素 1 つの取り出しと、スライス ( slice ) を利用した場合の取り出しの違いをちゃんと理解していますか? 投稿一覧へ戻る

Tags: miscellaneous , sequence , challenge , python

Published 2020年8月4日21:57 by T.Tsuyoshi

まずはちょっとした問題から。


文字列、リスト、タプルのいずれかを引数として 1 つだけ受け取る関数 first_last() を作成します。


この関数は、受け取ったシーケンスの最初と最後の 2 つの要素からなる引数と同じ型のシーケンスを返します。


すなわち、実行結果は以下のようになります。


first_last('1234')
# '14'

first_last(['a', 'b', 'c', 'd'])
# ['a', 'd']

first_last((1, 2, 3, 4))
# (1, 4)



では、実装してみてください (制限時間 15 分)。


def first_last(seq):
pass



さて、いかがでしょう? 簡単だったでしょうか?


出力結果が以下のようになってしまった方はいませんか?


first_last('1234')
# '14'

first_last(['a', 'b', 'c', 'd'])
# 'ad'

first_last((1, 2, 3, 4))
# 5



上のような出力結果になってしまった方は次のような実装をしたのではないでしょうか?


def first_last(seq):
result = seq[0] + seq[-1]
print(f"{result!r}")



シーケンスにおいて、インデックス番号を指定して要素を 1 つだけ取り出す、という行為は、その場所に保存されている「何か」を取得する、ということです。


それは元のシーケンスと同じ型のものかもしれないし、全然違う型のものかもしれません。


first_last('1234') では文字列が渡されてきています (文字列ももちろんシーケンスです)。


要素の 1 つ 1 つは文字 ( character ) です。それを + オペレータで繋いでいますから「文字列」が返ってきました。


first_last(['a', 'b', 'c', 'd']) はどうでしょう?


これも要素の 1 つ 1 つは文字ですから、結果は文字列になってしまいました。


first_last((1, 2, 3, 4)) では要素の 1 つ 1 つが数値ですから、+ オペレータを適用することで「和」が返ってきたんですね。


残念ながらこの実装方法では目的を達成できません。


それでは、と、isinstance() を利用して型を調べて対応した方もいるかもしれません。


でももっと簡潔な方法はスライス ( slice ) を利用することです。


def first_last(seq):
result = seq[:1] + seq[-1:]
print(f"{result!r}")


first_last('1234')
# '14'

first_last(['a', 'b', 'c', 'd'])
# ['a', 'd']

first_last((1, 2, 3, 4))
# (1, 4)



シーケンスをスライスする、という行為は、元のシーケンスと同じ型を持つ新しいシーケンスを作る、ということです。


シーケンスに対してインデックスやスライスを利用して要素の一部を取得する、という行為は日常的に行っていると思います。


ただ単に「値を取得する」というだけではなくて、このような違いがある、ということをちゃんと認識して使うようにしましょう!

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

0 comments

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

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