Python言語とは

Pythonはインタプリタ

次の5行は、Pythonで書いたHello, World!です。

def main():
    print("Hello, World!")

if __name__ == "__main__":
    main()

Pythonがインストールされている環境で、これを hello.py という名前のテキストファイルに保存し、コンソールで、pythonを実行し、引数にそのファイル名を指定すると

$ python hello.py
Hello World!

という実行結果を得ます。

Python言語で書かれたプログラムの実行には必ず、pythonというコマンドを介する必要があります。これはPython言語のインタプリタ(処理系)です。

Python 3を使いましょう

Python言語は大きく4世代に分類できます。

  • バージョン0: 1991年に0.9.0が公開された
  • バージョン1: 1994年にリリースされたバージョン
  • バージョン2: 2000年にリリースされて以来、もっとも永く使われていたバージョン
  • バージョン3: 2008年にリリースされ、2018年あたりからやっと標準となった印象があるバージョン

バージョン2の開発中に様々な拡張が行われたようです。そしてHistory of PythonというWikipedia上の記事にもあるように、バージョン3の仕様は、バージョン2との後方互換性を捨てて定められました。これだけの変更が行われたため、Python 2を使い続けた人が多かったのも頷けます。Porting Python 2 Code to Python 3は、もはや移植に近い内容な気がします。

そのため、Python言語は2種類ある、と言えます。

バージョン2のために書かれた多くのライブラリやソースコードは、バージョン3では動きません。しかし、多くのユーザはバージョン2を使い続け、教科書や教育内容、また多くのモジュールやパッケージもバージョン2を支持し続けつつ、バージョン3の開発も進めてきました。開発リソースの分割が原因で、バージョン3への移行はかなり遅れたようにも思います。

  • NumPyは0.16までPython 2.7とPython 3をサポートしていましたが、0.17.0からPython 3のみのサポートとなりました。これは2017年に決定されたそうです。
  • TensorFlowは2017年2月に公開されたバージョン1、2019年9月に公開されたバージョン2、いずれもPython 2をサポートしています。
  • Scikit-learnは2019年3月まで開発が続いたバージョン0.20までPython 2.7と3.4をサポートしていましたが、2019年5月に公開されたバージョン0.21以降はPython 3.5以降のみをサポートしています。
  • Anacondaは今でも、Python 2と3それぞれのディストリビューションを提供しています。

データサイエンスや機械学習を目的にPythonを新たに学ぶ人は、2020年以降はPython 2を学ぶ必要はなく、Python 3を学ぶのが良さそうです。テキストもPython 3に対応したものだけを探して大丈夫です。手に取った本がどちらのバージョンに対応しているかは、Python 2と3とでprint文が異なるので、すぐにわかるはずです。

# Python 2のprint文
print "Hello, World!"
# Python 3のprint文
print("Hello, World!")

そう、昔はprintは文で、関数ではなかったのです。

Python本体と標準ライブラリとサードパーティライブラリ

どんな言語も、言語の開発者が標準で提供する機能と、サードパーティが開発して提供する機能があります。 Pythonの場合は、次の三種類に分類されます。

提供方法機能、モジュール、パッケージ
Python本体に組み込んであるもの言語の文法、組み込み関数、組み込み定数、組み込み型、組み込み例外
Pythonと一緒にインストールされる標準ライブラリテキスト処理サービス、バイナリデータ処理、データ型、数値と数学モジュール、関数方プログラミング用モジュール、ファイルとディレクトリへのアクセス、データの永続化、データ圧縮とアーカイブ、ファイルフォーマット、暗号関連のサービス、汎用オペレーティングシステムサービス、並列実行、コンテキスト変数、ネットワーキングとプロセス間通信、インターネット上のデータの操作、構造化マークアップツール、インターネットプロトコルとサポート、マルチメディアサービス、国際化、プログラムのフレームワーク、Tkを用いたGUI、開発ツール、デバッグとプロファイル、ソフトウェアパッケージと配布、Pythonランタイムサービス、カスタムPythonインタプリタ、モジュールのインポート、Python言語サービス、各種サービス、MS Windows固有のサービス、Unix固有のサービス、取って代わられたモジュール群、ドキュメント化されていないモジュール
ユーザが選んでインストールして使うものNumPy、pandas、SciPy、flask, Pillow, purest, requests, Beautiful Soup, Scraps, SymPy, scikit-learn、…

Python本体に組み込んである機能以外はすべて、import文を用いて実行時に読み込むことを指定して、利用します。

Python本体の機能の例

変数型

真理値判定とブール演算

a, b = 1, 2
a > 0  # 変数aの中身は正値か
(a > 0) and (b > 0)  # 変数aおよびbの中身は共に正値か
(a > 0) or (b > 0)  # 変数aおよびbの中身の少なくとも一方は正値か
(a > 0) or not (b < 0)  # 変数aおよびbの中身の少なくとも一方は正値か

数値型

int a = 1
float b = 2.0

シーケンス型

list([1, 2, 3])  # リスト
list((1, 2, 3))  # リスト
[1, 2, 3]
tuple([1, 2, 3])  # タプル
tuple((1, 2, 3))  # タプル
(1, 2, 3)
range(3)  # レンジ
list(range(3))  # リスト
tuple(range(3))  # タプル

テキストシーケンス型

str("abc")
str('abc')
"abc"
'abc'

集合型

set
frozenset

マッピング型

dict
配列

Python本体は、1次元の配列しか持ちません。しかし、配列を要素にもつ配列も定義できるので、

リスト、タプル、辞書の3種類の配列を持ちます。 リストは更新可能な配列です。 タプルは更新不可能な配列です。 辞書はPerlの連想配列と似ていますが、数値と文字列を区別するキーを持ちます。

スライシング
条件分岐
if 条件:
    実行文1
if 条件1:
    実行文1
elif 条件2:
    実行文2
if 条件:
    実行文1
else:
    実行文2
if 条件1:
    実行文1
elif 条件2:
    実行文2
else:
    実行文3
ループ
for 変数 in 範囲:
    実行文1
while 条件:
    実行文1

抜けるのは break

内包表記

リスト、タプル、辞書などから、新しいリストや辞書を作る Python 独自の記法

リストの内包表記

[式 for 変数 in イテレート可能なオブジェクト]

はif条件文も使える。

[式 for 変数 in イテレート可能なオブジェクト if 条件式]

ネストも可能。

[式 for 変数名1 in イテラブルオブジェクト1
    for 変数名2 in イテラブルオブジェクト2
        for 変数名3 in イテラブルオブジェクト3]

集合の内包表記

{値 for 変数 in イテレート可能なオブジェクト}

はif条件文は使えない。

辞書の内包表記

{キー:値 for 変数 in イテレート可能なオブジェクト}

はif条件文は使えない。

zipとenumerate

zipは、2次元配列がないPythonならではの機能で、長さの同じイテラブルを組み合わせることができる。

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

{k: v for k, v in zip(keys, values)}

enumerateも同様。

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
source: list_comprehension.py
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
source: list_comprehension.py
enumerate()の例。

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
ジェネレータ式
ラムダ式

標準ライブラリの例

サードパーティ提供のライブラリの例

例えば、正弦関数のグラフを描くという目的の遂行には、以下の知識の活用が必要となります。

  • 数値計算に関する機能を多く提供するNumPyを読み込んで、その中の数値の配列を定義するメソッドarange()と正弦関数のメソッドsin()を利用します。
  • PythonとNumPyに対して各種グラフの描画機能を提供するグラフ描画ライブラリMatplotlibの中のpyplotモジュールを読み込んでメソッドplotを用います。

これらの知識を活用すると、次の短いプログラムが書けます。

def main():
    import numpy as np  # NumPy を読み込む
    import matplotlib.pyplot as plt  # Matplotlib を読み込む

    x = np.arange(-10, 10, 0.1)  # x座標を-10 から 10 まで 0.1 きざみで取得
    y = np.sin(x)  # 正弦関数の式を記述

    plt.plot(x, y)  # x, y をプロット
    plt.show()  # グラフを表示

if __name__ == "__main__":
    main()

このコードをファイルに保存して実行すると、次のグラフが画面に表示されます。

上のコードで読み込んだNumPyとMatplotlibは、とてもポピュラーなサードパーティライブラリです。Pythonでプログラムを書く際には、どんな機能がどのライブラリによって提供されているか、その利用のためには他にどのライブラリの機能を用いるか、の知識が欠かせません。でも慣れれば、ここまで整理しなくても自然に書けるので、煩雑に感じないでください。