Pythonはコードが書きやすい?ご冗談でしょう
という日経xTECHの釣り記事が炎上しました。特にツッコミが多かったのはこの部分
Pythonの構文ではコロンを多用する。if文の条件の後にコロン、elseの後にコロン、繰り返し処理を行うfor文でコロン、関数を定義するdef文でコロン、クラス定義でコロン、とにかくコロンだらけだ。
いや全部複合文のコロンじゃねーか!というのはさて置き、確かにPythonではコロンを目にする機会が多いような気がしていたのでこの機会に検証したいと思います。
同格としてのコロン
そもそもインデントでブロックを管理するPythonに何でコロンが必要なのか?という問いには公式のFAQにこう書かれています。
主に可読性を高めるため (実験的な ABC 言語の結果の一つ) に、コロンが必要です
更にこうとも。
これは、英語の標準的な用法です
確かにPythonらしい理由ではあります。
つまりPythonにとってのコロンとは前後のものを紐づける、すなわち同格としての役割を担うものだと言っているわけですね。
そう考えると以下の用法は全てそれに則っている気がします。
複合文(compound statement)
if a == b:
c = a + b
print(c)
上記日経の釣り記事で例示されているやつです。複合文のヘッダー行につけるコロンですね。
def
やclass
はもちろんのこと、if
とかfor
なんかもまあ確かに「~だったら実行するのはこのブロックですよ」という意味を思えば(多少強引な感はありますが)同格っぽいです。
ラムダ式
>>> a = [1, 2, 3]
>>> list(map(lambda b: b*2, a))
[2, 4, 6]
ラムダ式もdefの簡易版だと思えば納得のコロンです。
辞書の初期化
a = {
'b': 1,
'c': 2,
}
これは完全に同格ですね。
型アノテーション
>>> import dataclasses
>>>
>>> @dataclasses.dataclass
... class a:
... b: str = 'c'
... d: int = 0
...
>>> a()
a(b='c', d=0)
これも完全に同格です。
範囲を表すコロン(?)
さて、ここまでで殆どの用例をあげられたと思うのですが、大事なものを1つ忘れています。
スライスです。
>>> a = [1, 2, 3, 4, 5]
>>> a[1:3]
[2, 3]
これは完全に今までとは意味合いが異なっており、範囲を表します。
今までがisだとすればこれはtoでしょうか。
MATLABやExcelで見ない使い方ではないですが、1つの記号に2つの意味があるのは理念的にどうなんですかね?
2019/6/18 追記 範囲じゃないなこれ…
スライス表記の項目を見てたんですが、
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
もう1個コロン繋げられますね。
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> a[1:7:2]
[2, 4, 6]
strideはstep。各項目は省略できるのでこんな書き方もできます。
>>> a[::2]
[1, 3, 5, 7]
というわけで、スライスのコロンは範囲ではありませんでした。
英語の標準的な用法を謳うのであればこれはセミコロンじゃないかと思うのですが…
さらに増えるよ!
Python 3.8から新しい演算子が登場します。その名も**walrus operator**。
walrusってなんだろうと思って辞書ひいたらセイウチらしいんですけど、何故なんでしょう…セイウチ演算子…
コメントで横から見るとセイウチの顔になると教えていただきました(:=
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
要は式の中で代入できるよってことらしいです。
:=
は確かによく代入で使われる記号ですし分からんでもない。しかし結果としてまたコロンが増えました。
検証結果
「Pythonの構文ではコロンを多用するが、複合文のコロンはエディタに補完してもらえ」
抜け漏れがあれば教えてください。