Python(パイソン,と読む.ギリシア神話に登場するへび.)は,近年広く使われているインタプリタ言語で,特に機械学習・人工知能の分野でのプログラミングには欠かせない言語となっている.
C言語がコンパイル言語であるのに対して,Pythonはインタプリタ言語であり,プログラムを1行ごとに入力・実行することができる. また,C言語と同様にソースファイル(拡張子は .py )にプログラムをまとめて記述し,実行することも可能である. この場合も,ソースコードに対して行単位で逐次実行される.
このページでは,C言語をひと通り学習した人向けに,ざっと Python の文法の基礎を説明します.
配布している開発環境には,Python環境がインストールされていませんが,情報処理教室で作業する場合は,PCにインストールされているPythonが自動的に使用されるため,インストール不要です.
自宅などの自己所有のPC等でPythonプログラミングを行う際は,開発環境のインストールが必要です.(注意:現在使用されているVersionは Python 3 です.Python 2 は古いので使わないこと.)
VSCodium(または,VSCode, Windowsの)ターミナルで,以下のようにPythonインタプリタを起動する.バージョンは異なるかもしれない.
D:\cprog20\myprog> python Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>
このプロンプト(>>>)が表示されたら,プログラムの入力準備が完了した.という意味である.
Pythonはインタプリタ言語なので,以下の赤字の部分をキーボードから1行ずつ順次入力すると,その都度実行される.
>>> print('Hello world!') Hello world! >>> i=5+3 >>> print('i=', i) i= 8 >>> exit()
このように,簡単に計算プログラムを実行できるのがインタプリタ言語の特徴である.
動画による説明.コマンドプロンプトの起動からプログラム実行まで.
処理手順が長くなると1行ごとに入力するのは面倒で,間違いも多くなる.
そこで,C言語のようにあらかじめPythonのソースファイルを書いておいて,一度に実行することもできる.
この場合でも,機械語への翻訳は1行ごとに行われる.
以下を,ファイル名 test.py として USB の MyProg フォルダなどに保存する.
print('--- Calc. prog. ---')
i = 3 + 5
j = 4 * 5
print('ans = ', i * j)
C++の開発の場合と同様,VSCodiumなどのターミナルから実行可能である.
コンパイルすることなく,すぐに実行が始まる.
C言語の開発と同様,まず作業フォルダを開き,拡張子を.pyとしたソースファイル(スクリプトファイルともいう)を作成し保存する.
ターミナルから実行する.
# This is comment
print('Hello World!')
print('This is a "pen".')
実行結果
> python test.py
Hello World!
This is a "pen".
これだけでよい.
#
はコメント文である.C++の // , /* */
に相当する.
文字列は,"
と '
のどちらで囲っても,開始と終了がそろっていればOK.
(Cでは"
は文字列,'
は1文字と,役割が違う)
上の例のように," や ' 自身を表示したいときに,互いにエスケープしなくても利用可能.
print
は,C言語と異なり\n
を書かなくても改行が自動で追加される.
これを抑止したければ,以下のように end
に空文字を指定する.
print('ABC', end='') # 改行を抑制.''は,シングルクオーテーション2つ
print('XYZ')
実行結果
ABCXYZ
print
では,複数の値や変数をカンマ区切りで連続して出力できる.
この際,文字や数値の間に,区切り文字としてスペースが自動的に入る.
区切り文字を変更・抑制したいときは sep
変数を指定.
print(100, 200, 300)
print(100, 200, 300, sep = ',')
print(100, 200, 300, sep = ' | ')
print(100, 200, 300, sep = '') # 空白を抑制.''は,シングルクオーテーション2つ
実行例
100 200 300
100,200,300
100 | 200 | 300
100200300
キーボードからの入力には,input
を使う.
C言語の scanf()
に相当するが,input
の引数に,入力メッセージを渡すことができる.
入力された文字列は,戻り値として返されるので,他の変数などに代入可能.
ret = input('Input a number:')
str1 = input('input a number 1:')
str2 = input('input a number 2:')
sum = str1 + str2
print(sum)
実行例:
input a number 1:10
input a number 2:20
1020
この例では,画面に数値の合計である 30 ではなく,文字列が連結されて 1020 と表示される.
そこで,入力値を数値としたい場合は,int(), float()
を使って,数値に変換する.
(Cでいうところの atoi, atof, strtol, strtof
)
str1 = input('input a number 1:')
str2 = input('input a number 2:')
sum = int(str1) + int(str2)
print(sum)
実行例:
input a number 1:10
input a number 2:20
30
あるいは,最初からinput
の戻り値を数値に変換してから,変数に代入できる.
x = int ( input('input a number 1:') )
y = int ( input('input a number 2:') )
sum = x + y
print(sum)
Pythonでは,変数に何でも(型の種類を問わず)代入できる.
変数の型は実行時に動的に決まるので,事前に型名を決める必要はなく,さらには変数の宣言・定義も必要ない.
i = 10 # 整数.宣言無しで,いきなり代入可
print(i)
i = 'Hello' # 文字列を代入
print(i)
実行結果
10
Hello
型の種類を調べるには,type
を使う.
i = 10 # 整数.宣言無しで,いきなり代入可
print(i)
print(type(i))
i = 'Hello' # 文字列を代入
print(i)
print(type(i))
実行結果
10
<class 'int'>
Hello
<class 'str'>
print
で,文字列と変数の値をあわせて表示したければ,カンマ区切りで並べる.
i = 100 # 型名の指定は不要.
j = 200
print('Hello World! i=', i, 'j=', j)
変数は,数値だけでなく文字列もOK.ただし,演算が可能なもの同士でない場合はエラーが出る.
i = 'OMG!'
print(i + '1' ) # これはOK
print(i + 1) # これはNG. i は文字なので,数値を足せない
上記のサンプルでは,最後の行を実行した時点で,以下のようなエラーが出るはずである.
Pythonはインタプリタ言語なので,ソースコードの上から順に実行してゆき,エラーが出た時点で初めて実行が止まる.
このように Traceback (...) とのメッセージが出たら,何かしらのエラーが発生したと考えられるため,行数や内容をヒントにソースコードを修正しよう.
Traceback (most recent call last): File "D:\....\test.py", line 3, in <module> print(i + 1) TypeError: can only concatenate str (not "int") to str
C言語の printf()
風の書式指定が使いたい場合は,以下のように %(...)
で,表示したい変数名をカンマ区切りで列挙する.
name = 'Paul'
age = 40
height = 170.5
print('%s is %04d years old, height=%.2fcm.' % (name, age, height))
Paul is 0040 years old, height=170.50cm.
+, -, *, /, //, %, **
割り算の挙動が Python と C言語とで若干異なるが,その他は基本的に同じ.
C言語にはない **
は便利.
print(12 + 5)
print(12 - 5)
print(12 * 5)
print(12 / 5) # 浮動小数点で計算される.C言語では切り捨て
print(12 // 5) # 小数点以下を切り捨て
print(12 % 5)
print(12 ** 5) # べき乗
実行結果
17
7
60
2.4
2
2
248832
比較演算子の記号は,C言語と同じである.
<, > <=, >=, ==, !=
比較の結果,式の値として,True
か False
の値をとる.
print(2 > 3)
print(2 < 3)
実行結果
False
True
論理演算子は,そのまま and, or, not
と書く.
(C言語ではそれぞれ,&&
, ||
, !
でした)
print(1>2 or 1<2)
print(not True)
実行結果:
True
False
if
文if 条件式:
Cと異なり,条件式を丸かっこ () で囲うのではなく,条件式の最後にコロン :
をつける.
i = int(input('i=?'))
if i > 0:
print('正です.')
elif i < 0:
print('負です.')
else:
print('ゼロです.')
print('おわり.')
実行結果:
i=?10
正です.
おわり.
elif ...:
や else:
は,必要なければ省略できる.
pythonでは,コードブロックを字下げで表現するので,正しく字下げしないとエラーになる!
(これにたいして,C言語では,{}
で括られていれば,字下げありでもなしでも,何でもOKでした.)
Pythonでは,インデントはソースコードの見た目の問題ではなく, 字下げを綺麗に書かないとプログラムが正しく実行できないという素晴らしい言語仕様である.
while
文while 条件式:
if文とほぼ同様の書式. これも字下げ重要.
i=0
while i<=10:
print(i)
i+=1 # インクリメント.i++ は,何と文法エラー!
for
文for 変数 in オブジェクト:
C言語ではカウンタ変数などを用意して反復回数をカウントしますが,Pythonでは反復可能(Iterable)なオブジェクトを置きます.
例えば数値の連番の反復には,range
を使用します.
range(n)
で,0,1,2, ... , n-1 までの値の集合を表します.
for i in range(5):
print(i)
実行結果
0
1
2
3
4
range
は,(初期値, 終了値, 増分)と書くことができる.
増分を省略すると 1 となる.負数を与えることもできる.
for i in range(20, 10, -2):
print(i)
実行結果
20
18
16
14
12
多重ループの場合も,字下げをきれいに書きましょう.
print('---------------------')
for i in range(1,10):
for j in range(1,10):
print(i*j, end=' ')
print('') # これで改行が出力される
print('---------------------')
注:range
は,終了値には達しないので注意!
関数の定義は def
から書き始める.
def func():
print('Hello!') # 字下げ重要
# ↑↑↑↑ ここまでが関数 func() ↑↑↑↑
# ↓↓↓↓ ここから処理が開始される ↓↓↓↓
func() # 関数の呼び出し
func()
func()
実行結果
Hello!
Hello!
Hello!
引数の記述順に渡す.型名は不要.
def func(a, b):
print('a=', a, 'b=', b)
func(1, 2)
func(3.2, 4.9)
func('AAA', 'ZZZ')
実行結果
a= 1 b= 2
a= 3.2 b= 4.9
a= AAA b= ZZZ
戻り値はreturn
文を使用.C言語と異なり,複数の値を一度にreturnし,複数の変数で受け取れる!
def func(a):
a = 10
return a*2, a/2
a=1
print('a=', a)
b,c = func(a)
print('a=', a, 'b=', b, 'c=', c)
実行結果
a= 1
a= 1 b= 20 c= 5.0
簡単な引数は,いわゆる値渡しとなり,関数内で引数を変更しても,呼び出し元には影響しない.
ここでは説明しないが,変数の種類によっては参照渡しとなる場合がある.(ミュータブルオブジェクトと呼ばれるものがこれにあたる.)
リストは,Cでいう配列のようなもので,Pythonでは色々な型を混在できる.
このように変数をまとめて扱う機能は,一般にコンテナと呼ばれる.
普通の変数と同様,宣言時に型を指定する必要はない.
宣言には角かっこ [ ]
を用い,要素をカンマ区切りで書く.
添字は C と同様,オフセット 0 が先頭.
a = [10, 20, 30] # リストの初期化
print('a =', a)
print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
実行結果
a = [10, 20, 30]
a[0] = 10
a[1] = 20
a[2] = 30
負の添え字で逆順にアクセスできる.
a = [10, 20, 30] # リストの初期化
print('a =', a)
print('a[-1] =', a[-1])
print('a[-2] =', a[-2])
print('a[-3] =', a[-3])
実行結果
a = [10, 20, 30]
a[-1] = 30
a[-2] = 20
a[-3] = 10
リストの各要素は,個別に変更可能.
a = [10, 20, 30]
print('a =', a)
a[0] = 100
print('a =', a)
実行結果
a = [10, 20, 30]
a = [100, 20, 30]
配列の境界をはみ出ると...
a = [10, 20, 30]
print('a =', a)
print('a[2] =', a[2]) # これはOK
print('a[3] =', a[3]) # ???
print('a[4] =', a[4]) # OMG!
実行結果
a = [10, 20, 30]
a[2] = 30
Traceback (most recent call last):
File "test.py", line 4, in <module>
print('a[3] =', a[3]) # ???
IndexError: list index out of range
と,きちんとエラーが出る.
これは,リストの添字が有効範囲内にあるかを,逐一チェックしているからである.
その代償として,大きな配列のアクセスはC言語に比べて極めて遅い.
リストの中身は数値でなくても良い.
a = ['Oh', 'My', 'Goodness']
print('a = ', a)
print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
実行結果
a = ['Oh', 'My', 'Goodness']
a[0] = Oh
a[1] = My
a[2] = Goodness
さらに,リストの中身は数値と文字が混在しても良い.
a = ['Oh', 10, 'My', 20, 'Goodness']
print('a = ', a)
print('len(a) = ', len(a) )
print('a[0] =', a[0])
print('a[1] =', a[1])
print('a[2] =', a[2])
print('a[3] =', a[3])
print('a[4] =', a[4])
実行結果
a = ['Oh', 10, 'My', 20, 'Goodness']
len(a) = 5
a[0] = Oh
a[1] = 10
a[2] = My
a[3] = 20
a[4] = Goodness
array = [1, 3, 5, 10] # リスト
for i in array: # リストを使った繰り返し文
print(i)
実行結果
1
3
5
10
def func(a):
print('a=', a)
print('len(a) = ', len(a) )
a = [1,2,3]
func(a)
実行結果
a = [1,2,3]
リストのサイズ,型名は len()
, type()
で得られる.
a = [1,2,3]
print('len =', len(a))
print('type =', type(a))
実行結果
3
<class 'list'>
基本の手順はC言語と同じく,「開く」「読み書き」「閉じる」.
f = open('sample.txt', 'w') # 引数はCのfopen()と同じ.ファイル名とモード
f.write('Hello World!\nGood Bye!')
f.close()
ファイル名などは,変数を使おう.
fname = 'sample.txt'
f = open(fname, 'w') # 'w' は書き込みモード
data = 'Hello World!\nGood Bye!'
f.write(data)
f.close()
sample.txt が存在すると仮定する.
fname = 'sample.txt'
f = open(fname, 'r') # 'r' は読み込みモード
line = f.readline() # (改行コードも含め)1行読み込み
print(line)
f.close()
これだと1行しか読み込まれないので,
fname = 'sample.txt'
f = open(fname, 'r')
for line in f:
print(line) # line は1行分のデータ
f.close()
実行結果
Hello World!
Good Bye!
print
で表示すると,改行コードが余分に入るため,1行空行ができる.
この方法では,ファイルからの読み込み処理と,計算処理とを分離できる.
ファイルサイズがそこそこ大きくても効率よく自動的にメモリが確保され,高速に読み込める.
f = open('sample.txt', 'r')
lines = f.readlines()
f.close()
print(lines)
実行結果
['Hello World!\n', 'Good Bye!']
以下は 10万行分の数値の書かれたデータファイル data.csv を読み込んで,平均値を画面に出力する例である.
ファイルには 0∼1 までの乱数が書かれているので,平均値は 0.5 前後になる.
注:data.csvは1.3MB程度あるため,プログラムの実行テストが終わったら削除しておいた方が良い.
#
# ファイル内の数値を読み込んで平均値を計算
#
f = open('data.csv', 'r')
lines = f.readlines()
f.close()
N = len(lines)
print(N, 'lines in file.')
sum=0.0
for i in range(N):
# print(float(lines[i])) # 毎行表示
sum += float(lines[i])
print('average =', sum/N)
ファイル処理は,なんだかんだエラーが発生する.
書き込むファイルが他のアプリでロックされている.
読み込むファイルが存在しない.など.
エラー処理には,「例外処理」を使用する.詳しい説明はここでは省略.
fname = 'non-existing-file.txt' # 存在しないファイル名
try:
f = open(fname, 'r')
lines = f.readlines()
except:
print('読み込めなーい')
else:
print('読み込みました.')
print(lines)
f.close()
finally:
print('おしまい.')
実行結果:
読み込めなーい
おしまい.
Pythonプログラミングに際しては,これ以外にも多くの重要なトピックがある.
興味がある諸君はインターネットのサイトや書籍などを積極的に調べて学習してみよう.
ここでは詳しい説明は行わないが,さらなる詳細な解説は公式ドキュメント内にある「チュートリアル」「言語リファレンス」「ライブラリーリファレンス」を参照するとよい.
Pythonはインタプリタ言語であるため,自分でアルゴリズムをゼロから記述しても処理が遅いことが多い.
(逆に,C言語では下手なプログラムを適当に書いても,そこそこ高速に処理できる.)
したがって,いろいろな既存のパッケージ等をうまく組み合わせて使用するのが吉である.
(Pythonのパッケージの内部処理は,高速化のためにC言語などで書かれている.)
よく使われるパッケージ類などを紹介する.以下,外部サイトへのリンクです.
Pythonでは,機械学習のための様々なフレームワークが提案されている.現状,PyTorch と Tensorflow が2大勢力である.
今回の課題においては, Pythonで記述してみよう.拡張子は .py である.
キーボードから1以上の整数 n を入力し,n までの階乗 n! をすべて画面に表示するプログラムを作成せよ.
for
文を用いて,1からnまでの掛け算を順次おこなう.range()
の終端値に注意.n = input(???)
for i in range(...)
?? *= ??
print(???)
実行例
n = ? 10 (キーボードから入力,以下同様)
1! = 1
2! = 2
3! = 6
...
10! = ???
キーボードから3つの実数を入力すると,それぞれ大きい順,小さい順に並べ替えて,さらに平均値を画面に表示するプログラムを作成せよ.リストのソート機能が便利である.
次に,並べ替え結果と計算結果をファイル result.txt に出力せよ.
# リスト
l=[1,2,3,4,3,2]
print(l)
# ソーティング
l.sort()
print(l)
# 逆順ソーティング
l.sort(reverse=True)
print(l)
数値1:10.1
数値2:5.2
数値3:8.1
(出力されたファイル result.txt の中身)
大きい順 10.1 8.1 5.2
小さい順 5.2 8.1 10.1
平均値 7.8
キーボードから2以上の整数 n を入力し,n までの素数をすべて画面に表示せよ.
素数の計算部分を関数にすると良い.(ライブラリ関数にあるが,ここでは for
文,if
文を組み合わせて判定しよう)
実行例 n=? 100 2 3 5 7 11 13 ... ???