
【Python 雑談・雑学 + coding challenge】シーケンス ( sequence ) における インデックス ( index ) を使った要素 1 つの取り出しと、スライス ( slice ) を利用した場合の取り出しの違いをちゃんと理解していますか? 投稿一覧へ戻る
Published 2020年8月4日21:57 by T.Tsuyoshi
まずはちょっとした問題から。
文字列、リスト、タプルのいずれかを引数として 1 つだけ受け取る関数 first_last() を作成します。
この関数は、受け取ったシーケンスの最初と最後の 2 つの要素からなる引数と同じ型のシーケンスを返します。
すなわち、実行結果は以下のようになります。
では、実装してみてください (制限時間 15 分)。
さて、いかがでしょう? 簡単だったでしょうか?
出力結果が以下のようになってしまった方はいませんか?
上のような出力結果になってしまった方は次のような実装をしたのではないでしょうか?
シーケンスにおいて、インデックス番号を指定して要素を 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 ) を利用することです。
シーケンスをスライスする、という行為は、元のシーケンスと同じ型を持つ新しいシーケンスを作る、ということです。
シーケンスに対してインデックスやスライスを利用して要素の一部を取得する、という行為は日常的に行っていると思います。
ただ単に「値を取得する」というだけではなくて、このような違いがある、ということをちゃんと認識して使うようにしましょう!
文字列、リスト、タプルのいずれかを引数として 1 つだけ受け取る関数 first_last() を作成します。
この関数は、受け取ったシーケンスの最初と最後の 2 つの要素からなる引数と同じ型のシーケンスを返します。
すなわち、実行結果は以下のようになります。
first_last('1234')
# '14'
first_last(['a', 'b', 'c', 'd'])
# ['a', 'd']
first_last((1, 2, 3, 4))
# (1, 4)
# '14'
first_last(['a', 'b', 'c', 'd'])
# ['a', 'd']
first_last((1, 2, 3, 4))
# (1, 4)
では、実装してみてください (制限時間 15 分)。
def first_last(seq):
pass
pass
さて、いかがでしょう? 簡単だったでしょうか?
出力結果が以下のようになってしまった方はいませんか?
first_last('1234')
# '14'
first_last(['a', 'b', 'c', 'd'])
# 'ad'
first_last((1, 2, 3, 4))
# 5
# '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}")
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)
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)
シーケンスをスライスする、という行為は、元のシーケンスと同じ型を持つ新しいシーケンスを作る、ということです。
シーケンスに対してインデックスやスライスを利用して要素の一部を取得する、という行為は日常的に行っていると思います。
ただ単に「値を取得する」というだけではなくて、このような違いがある、ということをちゃんと認識して使うようにしましょう!
こちらの投稿にも興味があるかもしれません...
- 【Python 雑談・雑学 + coding challenge】Unicode の正規化処理 ( normalization ) を利用して、diacritical marks ( 発音区別符号 ) を取り除こう! テキスト解析の前処理としても重要です!
- 【Python 雑談・雑学 + coding challenge】文字列中の数字を抜き出して桁区切りをつけよう! 正規表現 (regular expression ) を使うと「えっ!?」っていうくらい簡単ですょ。lookahead と negative lookahead を使います。
- 【Python 雑談・雑学 + coding challenge】sorted 組み込み関数の key パラメータをうまく使って、カスタムオブジェクトを簡単にソートしよう! __getitem__、__len__ 特殊関数 ( special methods, dunder methods ) を実装すれば立派なシーケンス ( sequence ) です
- 【Python 雑談・雑学 + coding challenge】Python の pprint 機能を自分で実装してみよう! 自分なりの Pretty Print できちゃいます!!
0 comments
コメントはまだありません。
コメントを追加する(不適切と思われるコメントは削除する場合があります)