Pythonは 1990 年に Guido van Rossum により発表された、マルチパラダイム (手続き型 + オブジェクト指向 + 関数型)・動的型付 けのプログラミング言語である。ライブラリーが豊富で、Webアプリケーション のほか、機械学習などデータサイエンス分野で広く用いられるため、 2010 年代後半から急速に人気が高まってきている。
Pythonは、最新のバージョン 3.Xの他にバージョン 2.X もいまだに使われてい るが、2.7 が 2.X系列の最後であり、2.7のサポートが 2020年1月1日までとなって いるので、ここではバージョン 3.X について説明する。
ここではC言語と異なる部分を中心に説明する。
対話的な処理系はpython
というコマンドで起動できる。
対話的な処理系では、プロンプト(通常、>>>
)のあとに式を入力すれば、
その値を出力する。
>>> 1 + 1 2
quit()
またはexit()
と入力すれ
ば対話的な処理系を終了する。
Pythonを実行する環境として、IDLE(Pythonをインストールしていれば
idle
というコマンドで起動する), PyCharm, Spyderなどいくつか
の統合開発環境 (Integrated Development Environment, IDE) や Jupyter
Notebookというアプリケーションもよく使われるが、ここでは説明を割愛する。
変数は、次のように記号「=
」の左辺に書き、右辺の値を代入する。
(宣言は特になく、初めて使う変数に代入したときに変数が用意される。
このため、綴りの間違いには気を付ける必要がある。)
>>> x = 2 >>> x * 3 6
関数はキーワードdef
により定義することができる。
>>> def fact(n): ... if n == 0: ... return 1 ... else: ... return n * fact(n - 1) ... >>> fact(10) 3628800
入力が完了していないと判断するとPython処理系は、上のように第2プロンプ
ト「...
」を表示して入力の継続を促す。
関数定義は、キーワードdef
のあとに関数名(この例では
fact
)、丸括弧「(
〜)
」の中の仮引数のコンマ
区切りの並び(この例ではn
のみ)、コロン「:
」で始まる。
改行後に関数の本体を記述する。
関数の本体はインデント(字下げ)する。つまりdef
の位置よりも数
文字(この例では4文字)分下げる。インデントしている限り関数の本体が続い
ていると見なされる。
このようにPythonはインデンテーションが文法上意味を持つ言語で ある。(一方、CやJavaはどのようにインデントしてもプログラム の意味は変わらない。)
通常は、ファイルに関数などの定義を記述して、import
文で読み込む。
またPythonのソースファイルには.py
という拡張子を
つけるのが通例である。
ファイル factorial.py
>>> from factorial import * >>> fact(20) 2432902008176640000
この from
〜 import
*
という形式の
import
文は、〜というモジュール(ファイル名から拡張子
.py
を除いたもの)から変数や関数などの定義を読み込むことを意
味する。
整数や浮動小数点数のリテラルは他の言語と大きな違いはない。また、接尾辞
j
を整数や浮動小数点数リテラルにつけることで虚数を表
すことができる。
>>> (1 + 1j) / (1 - 2j) (-0.2+0.6j)
文字列リテラルは、二重引用符「"
」または一重引用符「'
」
で囲まれた文字列である。文字リテラルは存在しないので一重引用符/二重引
用符どちらを使っても意味は変わらない。
>>> "hello" 'hello' >>> 'world' 'world'
また三連続の二重引用符「"""
」または一重引用符
「'''
」で囲むと改行や一重引用符・二重引用符を含む
文字列を表すことができる。
>>> """Mike said "Hello!" ... and Anne said "Good Bye!" ... """ 'Mike said "Hello!"\nand Anne said "Good Bye!"\n'
引用符の前に接頭辞f
またはF
をつけると、
波括弧「{
」〜「}
」に囲まれた部分が式として評価さ
れ、文字列中に埋め込まれる。
>>> x = 13 >>> f"The factorial of {x} is {fact(x)}." 'The factorial of 13 is 6227020800.'
問:
では、f文字列のなかに波括弧(「{
」または「}
」)を
含めたいときはどうすれば良いか調べよ。
演算子は C や Java の演算子と似ているが、「/
」は整数同士の演算
でも通常の(小数になる可能性のある)除算である。整数としての除算の商を求めるには
「//
」を用いる。余りを求める演算子は「%
」
である。
>>> 1 / 3 0.3333333333333333 >>> 17 // 6 2 >>> 17 % 6 5
「**
」は累乗を求める演算子である。
>>> 2 ** 10 1024 >>> 2 ** 0.5 1.4142135623730951
画面に出力するにはprint
関数を用いる。いくつかの引数をコンマで区切って
与えるとそれらを順に出力する。
>>> y = 23 >>> print(x, "+", y, "=", x + y) 13 + 23 = 36
最後に、sep=
〜と指定すると、区切り文字を〜に変えることができる。
このように「キーワード=式
」のカタチで与える引数をキーワード引数
という。
(区切り文字を何も指定しないと上の例のように空白文字が区切りに使われる。)
>>> print(x, "+", y, "=", x + y, sep=',') 13,+,23,=,36
一方、input
関数はキーボードから文字列を読みこむ関数である。
int
関数(整数への変換)
やfloat
関数(浮動小数点数への変換)と組み合わせる
ことで、文字列をそれぞれ整数や浮動小数点数に変換することができる。
ファイル名 temp.py
条件分岐を表すif文はif
というキーワードのあと、条件式、コロン
「:
」で始まり、改行後に条件が成り立つときに実行する文を並べて
書く。
条件が成り立つ時に実行する文はインデント(字下げ)する。つまり
if
の位置よりも数文字(この例では4文字)分開始を下げる。
ここに複数の文を並べることもできる。同じ字下げ幅である限りは、
条件が成り立つ時には実行する。
条件が成り立たない時に実行する文は キーワードelse
、
コロン「:
」のあとに改行して書く。
また、if
と else
の間に elif
とい
うキーワード、条件式、コロン「:
」で始まり、改行後にインデント
した文の並び、というかたちをはさむことができる。この場合、上から順に条
件式を評価し、成り立つときに対応する文の並びを実行する。
条件式は and
(〜かつ〜)、or
(〜または〜)、not
(〜でない)などの論理演算子で組み合わせる
ことができる。
Python では(CやJavaと異なり)比較演算子は連ねることができるので、この 例は次のように書くこともできる。
上の例で使われているように、「#
」から行末まではコ
メントである。
決まった回数の繰り返しを実現するときにはfor文が使われる。次のように
キーワード for
、変数、キーワード in
、式、コロン「:
」
という形式で使われる。
ファイル名 temp2.py
ここでrange
関数は、range(n)
が、0 から n - 1 までの整
数の列を返すような関数である。
これを実行すると、変数i
に 0, 1, …, 4が順に代入され、次
のように出力される。
Hello 0 回目 Hello 1 回目 Hello 2 回目 Hello 3 回目 Hello 4 回目
他にrange
関数は次のようなカタチでも使われる。
range(n) | \(0\), \(1\), …, \(n - 1\) を返す。 |
range(m, n) | \(m\), \(m + 1\), …, \(n - 1\) を返す。 |
range(m, n, s) | \(m\), \(m + s\), …, \(m + k \cdot s\) を返す。 |
ただし、\(k\) は \(m + k \cdot s\) が \(n\) 未満となるような最大の \(k\) である。
繰り返しを表すwhile文はwhile
というキーワードのあと、条件式、コロン
「:
」で始まり、改行後に繰り返す文をインデントして並べて書く。
ここでprint
関数に、end=
〜とキーワード引数を指定すると最後に出力
する文字を変えることができる。(何も指定しないと改行文字が最後に出力さ
れる。)
これを実行すると、次のように出力される。
1000, 500, 250, 125, 62, 31, 15, 7, 3, 1,
なお、Python に do〜while 文に相当する構文はない。
リストは単純だが有用性の高いデータ型で、関数型言語など で多用されるデータ型である。配列と同様に(同種の)データを集めたものだが、 要素の追加・削除が可能である。
リストを構成するためには、角括弧([
〜]
)で
囲み、各要素をコンマ「,
」で区切って並べる。例えば、
[]
は空リストを表し、[2, 3, 5]
は3つの要素からなるリス
トを表す。
リスト内包表記 (list comprehension) は数学で使われる集合の表記に似た糖 衣構文 (syntax sugar) である。
>>> [x * y for x in range(1, 5) for y in range(5, 8)] [5, 6, 7, 10, 12, 14, 15, 18, 21, 20, 24, 28] >>> [x * x for x in range(1,11) if x % 2 == 1] [1, 9, 25, 49, 81]
リスト内包表記は、角括弧([
〜]
)のなかに最初に式を一
つ書き、そのあとに、「for
変数 in
式」というカタチか
「if
式」というカタチを並べたものである。(ただし並びの最初は
「for
〜」のカタチでなければいけない。)その値は
「for
変数 in
式」というカタチで与えられた繰り返し
の中で「if
式」というカタチで与えられた条件が成り立つときの
最初の式の値を順に並べたものになる。
問: 次のリスト内包表記の値は何か?
[x * y for x in [1,2] for y in [3,5,7]]
[(x, y) for x in [1,4,7] for y in [2,5,8] if x < y]
タプル(tuple, 組)は要素を「,
」(コンマ)
で区切って並べ、丸括弧「(
」と「)
」で囲んで表す。(文
脈によっては丸括弧を省略できる場合がある。)リストは通常、各要素は同
種のものからなるが、タプルは要素の種類が同一である必要はない。
タプルは以下の例のように関数の戻り値に使うこともできるし、代入文の左辺に 書くこともできる。
ファイル名 temp3.py
特に次のように書くと左辺の 2 つの変数への代入が同時に行われるので、2 つ の変数の内容を入れ替えることができる。
y, x = x, y
(この例ではタプルのまわりの丸括弧が省略されている。)
問:
3つの実数 a, b, c を受け取り、二次方程式 \(a x^2 + b x + c = 0\) の 2 つ
の解を組として返す関数 quadratic
を定義せよ。
標準ライブラリー関数のzip
は 2つ以上のイテラブルの
同じ位置の要素をタプルにしたもののイテラブルを返す関数である。イテラブ
ルの長さが異なる場合は、短い方にあわせる。
>>> list(zip([1,3,5,7,11], [2,4,6,10])) [(1, 2), (3, 4), (5, 6), (7, 10)]
高階関数は関数を引数に取る(あるいは 戻り値とする) 関数である。
リストに対しては、いくつかの高階関数が標準ライブラリーに用意されている。
例えば、map
は、リストの要素に一斉に関数を適用し、
その戻り値のリストを返す関数である。(正確にはイテラブル (iterable) を
受け取って、イテラブルを返す関数である。リストもイテラブルの一種だが、
一般にイテラブルを表示するためにはlist
関数でリストに変換する必要が
ある。)
このメソッドは次のように使用することができる。
>>> list(map(chr, [97, 98, 99, 100])) ['a', 'b', 'c', 'd'] >>> def twice(n): ... return 2 * n >>> list(map(twice, [97, 98, 99])) [194, 196, 198]
ここで、chr
は文字コードに対し対応する一文字からなる文字列を返す関数である。
ところで高階関数の引数として使うtwice
のような小さな関数にいち
いち名前をつけるのは面倒なので、名前をつけずに関数を表現する記法が用意
されている。これをラムダ式という。
(この名前は、かつて数学の一分野で、この目的のためにギリシャ文字の
「λ」が使われたことに由来する。)
例えば、lambda x: 2 * x
という式でtwice
と同等の関数を表
す。キーワードlambda
とコロン「:
」の間に仮引数のコンマ区切りの並びを、
コロンの右側に戻り値の式を書く。次はラムダ式の使用例である。
>>> list(map(lambda x: x * x, [2, 3, 5])) [4, 9, 25]
また、filter
は、リストの要素の中で、与えられた関数
の値を真にする要素だけのリストを返すメソッドである。
>>> list(filter(lambda x: x % 2 == 0, [2, 3, 5, 8])) [2, 8]
Python のジェネレーター関数 (generator function) はコルーチンの 一種 (stackless coroutine) を提供する。コルーチンとは、2つ以上のプログ ラムの実行単位が、 交互に制御を受け渡しながら実行されていく方式のことである。通 常の関数(サブルーチン)はリターンする(戻り値を返す)と、次に実行する 時はもう一度最初からになるが、コルーチンは次に実行する時に前回リターン した地点の続きから実行する。
ファイル名 fib.py
Pythonのジェネレーター関数ではyield
というキーワード
を使って値を生成する。
ジェネレーター関数を呼び出すと、すぐに関数内部のコードが実行されるので
はなく、一旦、ジェネレーターイテレーター (generator iterator) が作られ
て返される。このジェネレーターイテレーターを引数とし
てnext
関数を呼び出すと、ジェネレーター関数内部のコー
ドが実行され、yield
された値を返す。さらにnext
関数を呼
び出すと yield 文のつづきから実行が再開され、やはり、
次の yield された値を返す。
gen = gfib(100) print(next(gen)) # 1 を出力する print(next(gen)) # 1 を出力する print(next(gen)) # 2 を出力する print(next(gen)) # 3 を出力する print(next(gen)) # 5 を出力する print(next(gen)) # 8 を出力する
ジェネレーターイテレーターは for
文のin
の次の式でも使う
ことができる。
for
文 はジェネレーターイテレーターを受け取ったnext
関
数によって返される値を順に変数に代入してループする。ジェネレーター関数
の中のコードの実行がreturn文によりリターンするか、関数を抜けるとループ
を終了する。
この部分は「1 1 2 3 5 8 13
」と出力する。
ジェネレーターは必ずしも有限個の要素で終わる必要はない。 次の例は無限に yield する例である。
次のようにすると、
この部分は「1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
」と出力する。
問: 整数 \(n\) を引数として受け取り、最初は \(n\) を yield し、以降は、
という処理を繰り返すジェネレーター関数 hailstone
を定義せよ。
最後に、素数列を生成するプログラムを例として挙げる。 (ただし、この定義は効率面での改良の余地は大いにあると思われる。)
この primes()
は無限に素数を生成するので、例えば range
のように有限のものと zip
する。
このfor文は、
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
と20個の素数を出力する。