「もしnが列の長さより小さければTrue」での感動、みたいなもの。

不等号を使う時って、今まで数字が大きいか小さいか比べるっていうことでしか考えたことがなかった。
しかし、if n < len(array):(意訳:もしnが列の長さより小さければTrue)で、ある範囲の中にnの存在が確認できる書き方に出くわし、それが最初はパッと理解できなかったし、自分の中にそんな発想もなかった。

このコードには「リストのインデックスを使ってなんらかの処理を行いたい」という前提がある。

1
2
3
4
5
6
7
8
9
10
11
def checkIndex(n, array):
if n < len(array):
return array[n]
else:
return 'None'

if __name__ == "__main__":
print(checkIndex(3,[1, 2, 3]))
print(checkIndex(2,[1, 2, 3]))
print(checkIndex(1,[1, 2, 3]))
print(checkIndex(0,[1, 2, 3]))
1
2
3
4
None
3
2
1

最初はなんでこの書き方をするのかが理解できなかった。
よって、まずlen(array)は何を返すんだろうね? というところを確かめる。

1
2
>>> len(array)
3

len() は、リストを引数に指定するとリストの「要素数」を整数値で返す。

では要素数とはなんなのか。

1 | 2 | 3 ← 要素数
[1, 2, 3] ← 要素
0 | 1 | 2 ← インデックス

要素数とインデックスをまぜこぜで考えてしまうと混乱してしまう。

要素数はあくまで要素の個数であり、
インデックスはリストの部屋番号にすぎない。

そして要素が[1, 2, 3]となっているがために

1
2
>>> len(array)
3

これを要素の値「3」と捉えてしまうと、いよいよ大混乱のパレードに躍り出ることになる。

もっと噛み砕いて言うとlen(array)は、要素が「いくつあるのか」を整数で返す、のである。

次は不等号のチェックをする。

1
2
3
4
5
6
7
8
>>> 0 < 3
True
>>> 1 < 3
True
>>> 2 < 3
True
>>> 3 < 3
False

一番確認したかったのは3である。3は3よりも小さくない。3は3と同等である。
これで、先のコードはnが3だった場合、Falseを返すということがわかった。

ではなぜ、先のコードはnがリストの要素数よりも「(数が)小さいかどうか」を確かめるのか。
一番最初にも述べたとおり、今回のコードが「リストのインデックスを使ってなんらかの処理を行いたい」という前提があるからである。

さっきもみた通り、リストのインデックスは「0からはじまる」。
要素数が3でも、アクセスできるインデックスの最大値は「2」だ。

1 | 2 | 3 ← 要素数
[1, 2, 3] ← 要素
0 | 1 | 2 ← インデックス

先のコードを要素数が3つあるからと

1
if n <= len(array):

と書くと、「IndexError: list index out of range」(リストのインデックスが範囲外です)になる。

しつこいが、要素数は3でもインデックスは2までしかないのである。

いろいろ書いたが私が今回描きたかったことは実はこれではない(!)。

if n < len(array):len(array)は範囲を表現してる。

2 は 3 よりも小さいので、 1 から 3 の範囲の中に、2はかならず存在する。
と表現しているのが、なんか考え方すご!って思ったのだ。書きたかったのはここだけだったりする。

今回の場合、それはインデックスが存在するということを保証する表現になるから処理しても大丈夫なのだ。
(1から3という範囲には3も存在しているが、今回は「小さければ」という制限を設けて弾いている。理由は前述した)

ある数字 n がある数字 m よりも小さければnはmの範囲の中に存在するっていう見え方が「わかる! わかるんだけど、そう言われればそうなんだけど、そんなこと日常で考えたことなかったわ!」っていうある種の感動みたいな体験だった。

この数字と等号という道具の使い方は、スマートっちゅうかキレイだなと思った。

もうその考え方を知らない数時間前の自分にはもう戻れないというのも、また不思議な体験である。