Pythonの初歩

簡単な計算

Python に慣れるため、当分の間は電卓がわりに Python を使ってみましょう。実行を見て、お好きな方法で Python を起動してください。

まず足し算です。生の Python(python または python3 コマンド)ならプロンプト >>> の右側に、IPython(ipython または ipython3 コマンド)ならプロンプト In [1]: の右側に 123 + 456 と打ち込んで Enter キーを打ちます。Jupyter Notebook(Google Colaboratory を含む)なら最初の枠内に 123 + 456 と打ち込んで Shift + Enter です。次の行に答えが出ます。以下では Jupyter Notebook 風に表示しています。

123 + 456
579

123+456 のように詰めて書いてもいいのですが、ここでは見やすいように半角スペースを入れています。

掛け算は *、割り算は /、累乗は ** です(^ は累乗ではなくビットごとの排他的論理和です)。計算の順序は、通常の数式と同様、累乗が一番先で、その次が掛け算・割り算、最後が足し算・引き算です。

23 - 4 * 5
3
(23 - 4) * 5
95
1 / 3
0.3333333333333333
6.02 * 10 ** 23
6.019999999999999e+23

最後の e+23 は「×1023」の意味です。実数(浮動小数点数)の表示は上に示すように微妙に誤差が出ますが、これはコンピュータが内部で10進法ではなく2進法を使っているためです。

Python 2 では、C言語などと同様に、整数の割り算は整数に切り捨てましたが、Python 3 では / は実数(浮動小数点数)の範囲で計算します。整数の除算には // を使います。除算の余りは % です。例えば 7 // 3 は 2 になり、7 % 3 は 1 になります。

Python の浮動小数点数は一般的な IEEE 754 仕様ですが、整数は上限がありません(いわゆるbignum)。ただし、Python 3.10.7 から、DoS対策のため、10進変換などはデフォルト4300桁に制限されます。この制限を外すには環境変数 PYTHONINTMAXSTRDIGITS を 0 に設定するなどの方法があります(Built-in Types 参照)。

おもしろいことに、文字列を足し算、掛け算することもできます。文字列はダブルクオート " またはシングルクオート ' で囲んで表します:

"ほげ" + 'げほ'
'ほげげほ'
"ほげ" * 3
'ほげほげほげ'

値は変数に代入することができます。

x = 1 / 3
x * 3
1.0

この x のようなものを「変数」と呼びます。変数名は、大文字と小文字を区別します。

x
0.3333333333333333
X
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-45-b5fec669aca1> in <module>
----> 1 X

NameError: name 'X' is not defined

この NameError は変数名などを間違えたときに出ます。

対話型の環境では、一つ前の出力結果が、特別な変数 _ に入ります:

2 ** 16
65536
_ ** 2      # この場合 65536 ** 2 と同じ
4294967296

上の例では _ ** 265536 ** 2 と同じです。IPython では __ が二つ前、___ が三つ前です(四つ前はありません)。

いげた印 # より右側はコメント(説明のための注釈)です。実際に打ち込むときはコメントは必要ありません。

対話型の環境なら、これまでの例で示したように、式を打ち込めばそのまま答えが表示されますが、対話型でないプログラム中では print() 関数を使わないと出力されません:

print("Hello")
Hello

関数は print() 以外に、数値のリストの和を求める sum()、最大値や最小値を求める max()min() などが定義されています。念のため組み込み関数のリストを挙げておきますが、覚える必要はありません。

abs()delattr()hash()memoryview()set()
all()dict()help()min()setattr()
any()dir()hex()next()slice()
ascii()divmod()id()object()sorted()
bin()enumerate()input()oct()staticmethod()
bool()eval()int()open()str()
breakpoint()exec()isinstance()ord()sum()
bytearray()filter()issubclass()pow()super()
bytes()float()iter()print()tuple()
callable()format()len()property()type()
chr()frozenset()list()range()vars()
classmethod()getattr()locals()repr()zip()
compile()globals()map()reversed()__import__()
complex()hasattr()max()round()

sum([1, 2, 3, 4, 5])
15
max([1, 2, 3, 4, 5])
5

こういった組み込み関数の名前を上書きしたらどうなるでしょうか。

sum = 123
print(sum)

特に何も文句を言われませんね。でも本来の使い方をしようとすると、

sum([1, 2, 3, 4, 5])
TypeError: 'int' object is not callable

あらら! 元に戻すには、自分の作った sum を削除します:

del sum
sum([1, 2, 3, 4, 5])
15

ほかにどういう関数があるのでしょうか。三角関数は?

sin(pi / 2)
NameError: name 'sin' is not defined

駄目ですね。

数学関数はいくつかのライブラリで定義されています(標準ライブラリの math、サードパーティ(外部)ライブラリの NumPySciPy)。ライブラリ(library)とは図書館のことですが、コンピュータのライブラリは、いろいろな関数などが定義されている場所を意味します。

より技術的には、Python では、一つのファイルで構成されるものをモジュール、複数のファイルを含むディレクトリで構成されるものをパッケージと呼びます。ライブラリは、Python 標準ライブラリのようにモジュールやパッケージの集合を指すために使われますが、その意味はあいまいです。いずれにしても、読み込む際には以下で説明する import を使うので、ユーザから見た区別はありません。

ここでは Python の標準ライブラリの math モジュールを使います。そのためには、まず、次のように打ち込みます:

import math

これは math というものを読み込む(インポートする)ことを意味します。これで math. で始まる数学用のあれこれが使えるようになります:

math.pi   # 円周率
3.141592653589793
math.e    # 自然対数の底
2.718281828459045

IPython や Jupyter Notebook での浮動小数点表示の精度は、例えば %precision 4 と打ち込めば小数第4位までの表示になります。 %precision だけ打てばデフォルトに戻ります。より一般的には、print() の中で f"{式:.桁数f}" のような方法で表示を制御します:

print(f"{math.pi:.4f}")
3.1416

math.sin() で正弦が計算できます。引数はラジアン単位です。

math.sin(math.pi / 2)
1.0
math.sin(math.pi)
1.2246467991473532e-16

数値計算の誤差のため sin(π) は 0 にならず、1.22 × 10-16 という小さな値になりました。

import math の逆は del math です。

いちいち math.sin(math.pi / 2) などと書くのが面倒なら、from math import pi, sin, cos などと打ち込んでおけば、単に sin(pi / 2) と書くことができます。この逆は del pi, sin, cos です。

さらに極端に、math モジュールで定義されているものをすべてインポートする from math import * という命令もありますが、あまり推奨されていません。この逆は、いったん import math してから

for x in dir(math):
    if not x.startswith("_"):
        del globals()[x]

とすることが考えられます。インポートしたものや使った変数を全部消し去るには

for x in dir():
    if not x.startswith("_"):
        del globals()[x]

とします。

REPL(1行ごとに結果を返してくれる対話型環境)限定の話ですが、関数の括弧を閉じないとどうなるでしょうか。

>>> math.sin(math.pi / 2
... )
1.0

このように、続きの入力を促すプロンプト ... が出ますので、入れ忘れた ) を入力して Enter を押します。あるいは、わけがわからなくなったなら Ctrl + C で止まります(Emacs中では Ctrl + C を2回)。

ヘルプを読む

例えば print() という関数のヘルプを読むには、生の Python では help(print) としますが、IPython や Jupyter Notebook では ?print または print? と打ち込みます(うまくいかない場合は help(print) も試してください):

?print
Docstring:
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file:  a file-like object (stream); defaults to the current sys.stdout.
sep:   string inserted between values, default a space.
end:   string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
Type:      builtin_function_or_method

これで改行をなくすには end='' または end="" とすればよいことが推測できます(Python ではシングルクォート ' とダブルクォート " はまったく同じ意味です):

print("Hello", end="")
print(" World")
Hello World

? または ?? を前置または後置することでヘルプが表示される IPython の機能は、自分の作ったオブジェクト等にも適用されます:

x = [2, 3, 4, 5]
?x
Type:        list
String form: [2, 3, 4, 5]
Length:      4
Docstring:  
Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list.
The argument must be an iterable if specified.

このほか、Tab キーによる補完、%pwd%cd 何々 によるディレクトリ表示や移動、環境変数を表示する %env、Python ファイルをその場で実行する %run -i ファイル名、実行時間を計測する %timeit 何々、シェルでコマンドを実行する !command など、豊富な命令が使えます。詳しくは、? だけ打ち込むと出てくる IPython のヘルプ、%magic と打ち込むと出てくるマジックコマンドのヘルプをご覧ください。なお、デフォルトでは % を省略できてしまうので要注意です。省略できないようにするには %automagic off と打ち込みます。

終了のしかた

Python は quit() または exit() で終了します。IPythonは quit または exit でも終了します。Google Colaboratory は単にブラウザの窓を閉じるだけでかまいません。

ひつじがnひき

眠れない夜は、ひつじを数えてみましょう🐑🐑🐑🐑🐑🐑🐑🐑🐑🐑。

for i in range(1, 11):
    print("ひつじが", i, "ひき")

range(1, 11) は 1 以上 11 未満の整数を表します。Pythonはインデント(字下げ)でブロック構造を表しますので、必ず上の2行目は(半角の)スペースかタブでインデントします。多くの Python プログラマは(半角の)スペース4個でインデントする(そうなるようにテキストエディタを設定している)と思います。

ひつじが 1 ひき
ひつじが 2 ひき
ひつじが 3 ひき
ひつじが 4 ひき
ひつじが 5 ひき
ひつじが 6 ひき
ひつじが 7 ひき
ひつじが 8 ひき
ひつじが 9 ひき
ひつじが 10 ひき

もしもプログラムを間違えて止まらなくなったら、Ctrl + C を入力します(Emacs 環境なら Ctrl + C を2回入力します)。

眠れない夜がまだまだ続くときは、ひつじを数える関数を作りましょう。

def hitsuji(n):
    for i in range(1, n + 1):
        print("ひつじが", i, "ひき")

これで hitsuji(100) と打てば、ひつじが100ひき数えられます。

文字列に値を割り込ませる方法はいろいろあります。例えば

for i in range(1, 11):
    print(f"ひつじが {i} ひき")

という方法もあります。この方法なら、いろいろな書式指定ができます。例えば2桁右詰めなら

for i in range(1, 11):
    print(f"ひつじが {i:2d} ひき")

と書けます。print("ひつじが %2d ひき" % i) のような古いC言語スタイルの書式指定もできます。

フィボナッチ数列

Python では複数の代入を並行して行うことができます。このことを使えば、フィボナッチ数列の生成が次のように少しだけ簡単に書けます:

a, b = 1, 1
while a < 100:
    print(a)
    a, b = b, a + b

リストの形で返す関数にしてみます:

def fib(n):
    """n未満のフィボナッチ数列を返す"""
    r = []          # 空のリスト
    a, b = 1, 1
    while a < n:
        r.append(a) # リストにアペンド
        a, b = b, a + b
    return r

先頭に """...""" の形で与えたものは関数の説明(docstring)です。説明はヘルプに表示されます:

?fib
Signature: fib(n)
Docstring: n未満のフィボナッチ数列を返す
File:      ...
Type:      function

"""...""" または '''...''' は途中で改行が入ることを許す文字列です。説明(docstring)は途中で改行が入ることが多いので、一般に """...""" が使われます。ただ、上の例のように1行だけの場合は、"..." でもかまいません。

実行してみます:

fib(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

フィボナッチ数列のn番目を返すには次のように再帰を使うのが簡単です:

def fibn(n):
    if n < 3:
        return 1
    else:
        return fibn(n - 2) + fibn(n - 1)

テストしてみます:

[fibn(n) for n in range(1, 11)]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

他の言語のように、最初に一定の長さの配列を宣言しておきたい場合は、次のように、あらかじめ(例えば)0 を100個並べたものを作っておくことができます:

a = [0] * 100
a[0] = a[1] = 1
for i in range(2, 100):
    a[i] = a[i-2] + a[i-1]

0 の代わりに、未定義であることを示す None を使うほうがいいかもしれません。

高速な数値計算には NumPy(ナムパイ)というライブラリを使います(pip install numpy でインストールします)。NumPy は import numpy as np のようにして省略名 np でインポートします(この逆は del np です)。よく使うライブラリには伝統的な省略名があるので,それに従いましょう。NumPy を使えば、例えば 0 で初期化した長さ 100 の浮動小数点数の配列なら a = np.zeros(100)、同じく整数の配列なら a = np.zeros(3, dtype=int) のようにして作成・初期化できます。


Last modified: