Python プログラミング「Pythonの基礎1」
はじめに
ここではプログラミング言語 Python について解説します。
Python の特徴には以下のようなものがあります。
- プログラムが読みやすい
- 字下げで範囲を表す
- プログラム記述の統一性、一貫性が高い
- 実行が簡単
- コンパイルをしなくてよい
- 対話的な実行も可能
- 変数に型がない
- 数値も文字も同じように扱える
- 変数宣言が不要
このような特徴により、 Python はプログラムが比較的作りやすい言語として 知られています。また、 Python には多くの外部パッケージが提供されており、 これらを使うことで複雑な処理を短いプログラムで実現できます。
このページでは「Python の基礎1」として、Python にあらかじめ備わってい るデータ型、式、文などの基礎的な内容について説明します。
Python で使えるデータ型
データの型の種類
Python ではいくつかのデータの種類を扱うことができます。データの種類は データ型と呼ばれ、以下のようなものがあります。
- 数値
- 整数と実数
- 文字列
- 'abc'や"abc"のように表された文字が並んだ集まり
- リスト、タプル
- データが並んだ集まり
- リストでは各データ要素の内容や要素数を変えることができる
- タプルでは各データ要素の内容や要素数を変えることができない
- ディクショナリ
- キーと値のペアのデータが並んだ集まり
- キーで値を取得できる
数値
Python で扱う数値のデータ型には整数と実数があります。整数は個数や回数 などの数値を表すときに使用し、実数は長さや質量などの小数も含む値を表す ときに使用します。
Python では整数型の値で扱える数値の範囲に上限・下限はなく、コンピュー タのメモリが許す限りの桁数の整数値を扱うことができます。実数で扱える数 値の範囲はC言語の倍精度(double)変数と同じになっており、およ そ±2.3E-308 〜 ±1.7E+308の範囲の値を扱うことができ、値の有効桁数は約 15桁となっています。
小数部のない実数は整数なので、整数というデータ型は不要にも思えますが、 整数と実数やそれぞれ役割が違うので、どちらのデータ型も必要となります。 整数は小数部がないため、その値を厳密に表すことができます。それに対して 実数には有効桁数が存在するため、例えば実数の1は、厳密に1を表すのではな く、小数点以下約15桁の誤差を含みます。そのため個数や回数など厳密に決まっ た値を表すときには整数を使用し、連続的に変化する値を表すときには実数を 使用します。
# 整数値を代入 a = 4 b = 3 # 計算結果は必要に応じて整数値になったり実数値になったりする print(a+b) # 7 足し算 print(a/b) # 1.3333333333333333 割り算 print(a**b) # 64 べき乗 print(int(10/3)) # 3 整数に変換 print(float(10)) # 10.0 実数に変換
文字列
文字列の作成
シングルクォート(')やダブルクォート(")で囲まれた文字は文字列として扱わ れます。シングルクォートとダブルクォートはどちらも同じように使用できま すが、シングルクォートを含む文字列はダブルクォートで囲み、ダブルクォー トを含む文字列はシングルクォートで囲みます。
# 文字列を表示 print('text') # text # シングルクォートを含む文字列はダブルクォートで囲む print("don't") # don't
文字列の演算
文字列と文字列の和は文字列の結合となり、文字列の定数倍は文字列の繰り返 しになります。
a = 'This is ' b = 'a pen' # 文字列の和は結合 print(a+b) # This is a pen c = 'Ha '*4 # 文字列の積は繰り返し print(c) # Ha Ha Ha Ha
文字列の部分要素の取得
文字列はC言語の配列のようにも使え、文字列 s の s[0] で文字列の1文字目、 s[1] で2文字目を取得できるなど、0から始まる要素番号でその番号に対応す る1文字を取得することができます。
要素番号をマイナスで指定すると末尾から数えた文字を取得できます。文字列 s の s[-1] で末尾から1文字目、 s[-2] で末尾から2文字目を取得でき、文字 列の長さを n としたとき、 s[-1] は n-1 番目の要素、 s[-2] は n-2番目な どに対応した1文字を取得することができます。
s[a:b]とすると aからbの前の文字まで(a≦x<b)の文字列を取得でき、 a を 省略した場合は先頭からbの前の文字まで、 b を省略した場合は a から末尾 までの文字列を取得できます。
s = 'abcdefg' # 要素番号で要素を指定 print(s[0],s[1]) # a b # マイナスを付けると末尾から print(s[-1],s[-2]) # g f # コロン(:)を使うと範囲指定できる print(s[2:5],s[-3:-1]) # cde ef # 範囲の始まり、終わりは省略できる print(s[4:],s[:-2]) # efg abcde
リスト
リストは複数のデータをまとめたもので、1つの変数に複数の値を入れること ができます。それぞれの要素は要素番号を使って指定できます。要素番号は文 字列と同じようにゼロからはじまるので、要素数3のリストLはL[0], L[1], L[2]で要素を指定します。
作成と追加
[ ] を使うとリストを作成できます。
リストはいくつか機能を持っていて、変数名の後にドット(.)を付けて関数名 を書くと、その関数で定義されている機能を使うことができます。append は 要素を追加する関数で、値を指定するとその値がリストに追加されます。
リストの各要素のデータ型は任意に指定できるので、整数、実数、文字列など が入ったリストを作ることができます。リストにリストを入れることもできる ので、2次元配列なども作ることができます。
L = [0, 1, 2] # 初期値を入れてリストを作成 print(L) # [0, 1, 2] L = [0]*3 # 繰り返しで作成 print(L) # [0, 0, 0] L = [0, 1] L.append(2) # 要素の追加 print(L) # [0, 1, 2] L = [0, 'abc', 3.14, [1,2]] # 型の違うデータを混ぜてももよい print(L) #[0, 'abc', 3.14, [1, 2]]
部分要素の取得
リストでも文字列と同じように要素番号を使って各要素を指定し、値の取得や 代入ができます。
要素番号をマイナスで指定すると末尾から数えた要素を指定できます。リスト L の L[-1] で末尾から1番目、 L[-2] で末尾から2番目の要素を指定でき、リ ストの要素数を n としたとき、 L[-1] は n-1 番目の要素、 L[-2] は n-2番 目などに対応した要素を指定することができます。
L[a:b]とすると aからbの前の要素まで(a≦x<b)の部分要素のリストを取得で き、 a を省略した場合は先頭からbの前の要素まで、 b を省略した場合は a から末尾までの要素を取得できます。
L = [0, 1, 2, 3, 4, 5] print(L[0],L[1]) # 0 1 print(L[-1],L[-2]) # 5 4 print(L[2:5],L[-3:-1]) # [2, 3, 4] [3, 4] print(L[4:],L[:-2]) # [4, 5] [0, 1, 2, 3]
リストの操作
リストにある機能を使って、要素の並べ替え、追加、削除などができます。
L = [3, 0, 2, 1, 5, 4] L.sort() # ソート(小さい順に並べ替え) print(L) # [0, 1, 2, 3, 4, 5] L.extend([6,7]) # 拡張 print(L) # [0, 1, 2, 3, 4, 5, 6, 7] L.reverse() # 反転 print(L) # [7, 6, 5, 4, 3, 2, 1, 0] L.insert(3,100) # 挿入 print(L) # [7, 6, 5, 100, 4, 3, 2, 1, 0] L.remove(100) # 値で削除 print(L) # [7, 6, 5, 4, 3, 2, 1, 0] del L[1] # 要素番号で削除 print(L) # [7, 5, 4, 3, 2, 1, 0] length = len(L) # 要素数 print(length) # 7 L.clear() # 全要素削除 print(L) # []
タプル
タプルはリストと同じく複数のデータをまとめたもので、要素番号や範囲を用 いて各要素を指定できます。ただし、リストとは異なり各要素の値を変更する ことがでないので、要素の値や並び順の変更はできません。
タプルは要素の変更ができないので用途が限定されそうですが、Python では 複数の定数を扱うときタプルがよく使われます。
作成と部分要素
( ) を使うとタプルを作成できます。値をカンマ(,)でつないだものはタプル とみなされるので、括弧なしでもタプルを作ることができます。
部分要素の指定の方法はリストと同じです。
t = (0, 1, 2) # 初期値を入れて作成 print(t) # (0, 1, 2) t = 0, 1, 2 # 括弧なしでもよい print(t) # (0, 1, 2) t = (0,1)*2 # 繰り返しで作成 print(t) # (0, 1, 0, 1) t = (0, 1, 2, 3, 4, 5) # 部分要素指定はリストと同じ print(t[1],t[2:5]) # 1 (2, 3, 4)
要素数1のタプル
括弧は(1+2)/3のように式計算でも使われるので、括弧内に値を1つ書くと数式 の括弧とみなされ要素数1のタプルとはなりません。
要素数1のタプルを作るときは値の後にカンマ(,)を付けます。
i=(10) # 数式の括弧とみなされる print(i) # 10 t=(10,) # タプルにするにはカンマが必要 print(t) # (10,)
ディクショナリ(辞書)
ディクショナリとはキーと値を持つデータで「d = {キー : 値 }」のように表 され、各要素はキーを使って d[キー] で指定できます。
要素の指定方法はリストに似ていますが、リストでは要素をゼロから始まる続 き番号で指定するのに対し、ディクショナリのキーには連続でない整数値や文 字列も使用できます。
作成、追加、削除
{ } を使うとディクショナリを作成できます。
値の取得や変更ではキーを用いて要素を指定します。存在しないキーで値を代 入するとそのキーと値の組となる新しい要素を追加することになります。存在 しないキーで値を取得しようとするとエラーとなります。要素の削除には del を使います。
d = {'CA':3,'H1':6,'H2':8,'N':3} # 作成 print(d) # {'CA': 3, 'N': 3, 'H2': 8, 'H1': 6} v = d['H2'] # 値の取得 print(v) # 8 d['O'] = 5 # 値の追加 print(d) # {'CA': 3, 'N': 3, 'O': 5, 'H2': 8, 'H1': 6} d['CA'] = 0 # 値の変更 print(d) # {'CA': 0, 'N': 3, 'O': 5, 'H2': 8, 'H1': 6} del d['N'] # 値の削除 print(d) # {'CA': 0, 'O': 5, 'H2': 8, 'H1': 6}
ディクショナリを print などで表示するときの要素の並びは不定なので、表 示する毎に並びが変わりますので注意して下さい。
ディクショナリの利用
ディクショナリ使用の応用例としてリストに入っている元素について、各元素 種の個数を求めるプログラムを以下に示します。
L = ['H','H','N','C','H','H','C','O','O','H'] # 元素名 d = {'C':0, 'H':0, 'O':0, 'N':0} # 各元素の数を数える準備 d[L[0]] += 1 d[L[1]] += 1 # ディクショナリ d では元素名がキーに d[L[2]] += 1 # なっているので、リスト L の各要素を d[L[3]] += 1 # キーにして d の各要素の値に 1 を加えると d[L[4]] += 1 # 各元素の数がわかる d[L[5]] += 1 d[L[6]] += 1 d[L[7]] += 1 d[L[8]] += 1 d[L[9]] += 1 print(d)# {'C': 2, 'H': 5, 'O': 2, 'N': 1} 各元素の数
上記のプログラムは後述するfor文を使って繰り返し処理にすると簡潔に書けます。
Python の式や文
行とブロック
1行が実行の単位(ステートメント)
Python ではプログラムを上から1行ずつ順に実行していきます。
セミコロン(;)を使うことで行をつなげることができ、1行に複数の式を書くこ ともできます。
式が長くなりプログラムが見づらいときは、括弧を使って1行を複数の行で表 すこともできます。
a = 1 # 1行が実行の単位 a = 1; b = 2 # セミコロンでつなげられる a = (1 + 2 + 3 + 4) # 括弧を使うと複数行で書ける
字下げでブロックを表す
プログラムの特定の範囲はブロックと呼ばれ、 Python ではこのブロックの範 囲を字下げで表します。
字下げの量が同じ範囲が1つのブロックとなり、ブロック内に更に字下げ量を 増やした別のブロックを作ることもできます。
後述する if 文は指定した条件で、プログラムの特定の範囲を実行するか否か を制御します。このときのプログラムの範囲はブロックで表します。
if x > y: # コロンがブロックの始まり x = 1 # 字下げでブロックを表す y = 2 # 字下げの終わりがブロックの終わり # 字下げの数でブロックの違いを表す if x == 1: # 1つ目の始まり if y == 2: # 2つ目のブロックの始まり x = 3 y = 4 # 2つ目のブロックの終わり else: x = 5 y = 6 # 1つ目のブロックの終わり
字下げでブロックを表すのが Python の大きな特徴で、これにより字下げの揃っ た見やすいプログラムを作ることができます。
変数への代入
通常の代入
変数に値を代入するときはイコール(=)を使います。このイコールは数学の等 号とは異なり両辺が等しいという意味ではなく、左辺の変数に右辺の値や変数 を入れることを意味します。
変数に値を代入すると変数が作られ、それ以降その変数は代入された値を保持 します。 Python ではC言語とは異なり、変数を使用するときあらかじめ変数 宣言をする必要はありません。また、 Python の変数には型がないため、あら ゆるデータ型の値を宣言なしで変数に代入することができます。
1行で複数の変数にそれぞれ異なる値を代入するときにはタプル代入を用い、 同じ値を代入するときにはマルチターゲット代入を使用します。
a = 1 # 通常の代入(整数) s = 'abc' # 通常の代入(文字列) print(a,s) # 1 abc a, s = 1, 'abc' # タプル代入(タプルの括弧は省略されている) print(a,s) # 1 abc a = b = c = 1 # マルチターゲット代入 print(a,b,c) # 1 1 1
拡張代入
変数 a に整数値が入っていて、a に 1 加えるときには a = a + 1 と書きま す。このとき拡張代入を用いると a += 1 のように、a を1回書くだけで済み ます。拡張代入は引き算(-)、掛け算(*)、割り算(/)でも使用できます。
これらはC言語の複合代入演算子と同じように使えます。ただし、C言語にある、 1を足す演算子(++)や1を引く演算子(–)は、 Python では使用できません。
文字列に += を用いると、もともと入っていた文字列に新たな文字列をつなげ ることができます。
a = 1 a += 1 # a = a + 1 と同じ(※C言語にあるi++は使えない) print(a) # 2 s = 'abc' s += 'def' # 文字列の場合は連結 print(s) # abcdef
データの可変性と不変性
数値、文字列、タプルは不変
数値、文字列、タプルは不変性のデータ型なので、値を変更することはできま せん。
文字列の特定の文字を別の文字で置き換えようとしたり、タプルの要素を変更 しようとするとエラーになります。
整数や実数などの数値も不変性のデータ型ですが、値は1つであり、数値が入っ た変数に別の数値を入れると値が入れ替わるので、通常は数値の不変性を意識 する必要はありません。
s = 'back' print(s) # back print(s[0]) # b s[0] = 'p' # エラー s = 'p' + s[1:] # 新たな文字列を作成して代入 print(s) # pack
リスト、ディクショナリは可変
リストやディクショナリは可変性のデータ型なので、各要素の値を変更するこ とができます。
あるリストを保持する変数を別の変数に代入すると、それら2つの変数は同じ リストを共有することになり、一方の変数でリストの要素を変更すると、もう 一方のリストの要素も変更されます。
複数の変数でデータを共有したくない場合は、代入ではなくコピーを使います。 リストLのコピーは a = L[:] とし、ディクショナリdのコピーは a = d.copy() とします。
a = [1,2,3] b = a # b は a と同じデータを持つ a[0] = 4 # a[0] を変更すると b[0] も変わる print(a) # [4, 2, 3] print(b) # [4, 2, 3] a = [1,2,3] b = a[:] # a の全要素をコピー a[0] = 4 # a[0] を変更しても b[0] は変わらない print(a) # [4, 2, 3] print(b) # [1, 2, 3]
if文
if, else, elif の使い方
if文を用いると、プログラムの特定の箇所を実行するか否かを制御できます。
if文では、 if の後に条件式を書き、コロン(:)で条件の終わりを示します。 if文の条件式が成り立つとき、if文の下に位置する字下げの量の等しいブロッ クの範囲が実行されます。
else を用いると、if文の条件式が成り立たないとき実行されるブロックを指 定できます。
a = 1 if a == 1: print('a は 1') # 条件が成り立つとき実行される else: print('a は 1ではない') # 条件が成り立たないとき実行される if a == 1: print('a は 1') elif a == 2: # else と if の組み合わせ elif で条件を付け加えられる print('a は 2') else: print('a は 1でも2でもない')
条件式で使える主な演算子を以下に示します。
演算子 | 意味 |
---|---|
a == b | a と b は等しい |
a != b | a と b は等しくない |
a < b | a は b より小さい |
a <= b | a は b 以下 |
a > b | a は b より大きい |
a >= b | a は b 以上 |
and, or で複数条件の組み合わせ
条件式の論理和や論理積にはそれぞれ or と and を使います。
or と and を組み合わせて使用したときには、 and の方が優先順位が高いの で先に評価されます。ただし、数式と同じように括弧を使うと優先順位を変え ることができるので、なるべく括弧を使って優先順位がわかるように書いた方 が、プログラムがわかりやすくなります。
a, b = 1, 2 if a == 1 and b == 2: # 「かつ」 は and print('a は 1 かつ b は 2') if a == 1 or b == 1: # 「または」 は or print('a は 1 もしくは b は 1') if ((a == 1 or a == 2) and # 長い条件式は括弧に入れると改行できる (b == 1 or b == 2)): print('a は 1か2、かつ、b は1か2')
リストの要素の有無
if文でリスト内に特定の要素があるかどうかを調べるときには in を使います。
not in を使うと特定の要素がないことを調べることができます。
L = [1,2,3,4] if 3 in L: # in で要素の存在を確認できる print('L に 3 がある') if 5 not in L: # not in で要素に存在しないことを確認できる print('L に 5 がない')
ディクショナリの要素の有無
if文でディクショナリ内に特定のキーや値があるかどうかを調べるときには in を使います。
ディクショナリ d において、キーの有無を調べるときはそのまま [キー] in d を使いますが、値の有無を調べるときは [値] in d.values() を使い、キー と値の有無を調べるときは [(キー, 値)] in d.items() とします。
d = {'a':1, 'b':2, 'c':3} if 'a' in d: # ディクショナリではキーの存在を確認できる print('d に キーが a の要素がある') if 1 in d.values(): # values で値の存在を確認できる print('d に 値が 1 の要素ある') if ('b',2) in d.items(): # items でキーと値の存在を確認できる print('d に キーが bで値が 1 の要素がある')
while文
while, continue, break の使い方
while文を用いると、プログラムの特定の箇所を繰り返し実行できます。繰り 返し実行のことをループとも呼びます。
while文では、 while の後に条件式を書き、コロン(:)で条件の終わりを示し ます。while文の条件式が成り立つとき、while文の下に位置する字下げの量の 等しいブロックの範囲が繰り返し実行されます。
continue 文を使うと、それ以降は実行せず繰り返しの先頭に戻り実行を続け ます。
break 文を使うと、それ以降は実行せず繰り返し処理も終了します。
i = 0 while i < 4: i += 1 print(i) # 1 # 2 # 3 # 4 # i が4より小さいとき i に 1 を加え、その値を表示している # continue との組み合わせ i = 0 while i < 4: i += 1 if i == 3 : continue # 繰り返しの先頭に戻る print(i) # 1 # 2 # 4 # i に 1 を加えたあと、 i が 3 であるとき表示をせず繰り返しを続ける # break との組み合わせ i = 0 while i < 4: i += 1 if i == 3 : break # 繰り返し処理を終了する print(i) # 1 # 2 # i に 1 を加えたあと、 i が 3 であるとき繰り返し処理を終了する
無限ループと末尾での条件判断
通常のwhile文はループの先頭で条件判断するので、条件によってはループ内 の処理が一度も実行されないことがあります。
i = 10 while i < 10: print(i) i *= 2; # なにも表示されない
while の条件式を True にすると、繰り返し処理をし続ける無限ループを作る ことができます。
この無限ループを用いると、ループ内の処理は最低でも1回実行され、末尾で の条件判断ができます。
i = 10 while True: # 無限ループ print(i) i *= 2 if not i < 10 : break # if 文でループを抜ける # 10 が表示される
i の初期値が 1 のときは、上の2つの while 文ではどちらも 1, 2, 4, 8 を が表示さますが、i の初期値が 10 のとき、上のwhile文では何も表示されず、 下のwhile文では10が表示され、C言語の do-while と同じ処理ような末尾での 条件判断ができます。
for文
リスト、タプル、ディクショナリなど複数の要素をもつデータ型の各要素を対 象にして繰り返し処理を行うときは for 文を使います。
for文は「for [要素が代入される変数] in [対象となるデータ]」と書き、[対 象となるデータ]の各要素が[要素が代入される変数]にコピーされ、データの 要素数だけ繰り返し処理が行われます。
リストを使ったfor文
リスト s において「for x in s:」とすると、 s の各要素が x にコピーされ、 要素数だけ繰り返し処理が行われます。
s = ['abc', 'def', 'ghi'] for x in s: # リストを直接指定 print(x) # 各要素の値が表示される # abc # def # ghi
「for i,x in enumerate(s):」とすると、 i には各要素の番号、 x には各要 素がコピーされ要素数だけ繰り返し処理が行われます。
s = ['abc', 'def', 'ghi'] for i,x in enumerate(s): # enumerate でリストを指定 print(i,x) # 要素番号と要素の値が表示される # 0 abc # 1 def # 2 ghi
ディクショナリを使ったfor文
ディクショナリ d において「for x in d:」とすると、 d のキーが x にコピーされ、 要素数だけ繰り返し処理が行われます。
d = {'a':1, 'b':2, 'c':3} for x in d: print(x) # キーが表示される # a # b # c
「for x in d.values():」とすると、d の値が x にコピーされ、 要素数だけ繰り返し処理が行われます。
d = {'a':1, 'b':2, 'c':3} for x in d.values(): print(x) # 値が表示される # 1 # 2 # 3
「for k,v in d.items():」とすると、d のキーが x、値が v にコピーされ、 要素数だけ繰り返し処理が行われます。
d = {'a':1, 'b':2, 'c':3} for k,v in d.items(): print(k,v) # キーと値が表示される # a 1 # b 2 # c 3
rangeを使ったfor文
range を使うと特定の範囲の整数値を生成できるので、for文と組み合わせる とその整数値に対応した繰り返し処理を行うことができます。
「for i in range(3)」とすると、0≦i<3 の範囲の整数が i にコピーされ繰 り返し処理が行われます。
for i in range(3): # 0≦i<3 の範囲 print(i) # 0 # 1 # 2
「for i in range(2,5)」とすると、2≦i<5 の範囲の整数が i にコピーされ繰 り返し処理が行われます。
for i in range(2,5): # 2≦i<5 の範囲 print(i) # 2 # 3 # 4
「for i in range(3,9,2)」とすると、3≦i<9 の範囲で2ずつ増える整数が i にコピーされ繰り返し処理が行われます。
for i in range(3,9,2): # 3≦i<9 の範囲で2ずつ増える print(i) # 3 # 5 # 7
range を使うとC言語の for 文のような動作をさせることができます。
C言語では配列変数の各要素の値を使うとき for 文を用い i などの変数で要 素番号指定して繰り返し処理を行いますが、 Python では通常 for 文と range を組み合わせて要素番号を指定する方法ではなく、リストを使ったfor文 で示したように、要素番号を指定せず直接各要素のコピーで繰り返し処理を行 います。
rangeを使ってリストの値を変更
リスト s において「for x in s:」とすると、 s の各要素が x にコピーされ て繰り返し処理が行われるため、繰り返し処理内で x の値を変更しても、そ の変更はリスト s の要素に反映されません。
s = ['abc', 'def', 'ghi'] for x in s: # リストを使ったfor文 x += '*' print(s) # 要素の値は変わらない # ['abc', 'def', 'ghi']
for 文を用いて、リストの各要素の値を変更するときには、for 文と range を組み合わせて、要素番号を指定して値を変更します。
このとき「len(s)」を使用して、リスト s の要素数を取得します。
s = ['abc', 'def', 'ghi'] for i in range(len(s)): # リストとrangeを使ったfor文 s[i] += '*' print(s) # 要素の値が変わる # ['abc*', 'def*', 'ghi*']
ただし、上記の方法は以下で説明するリスト内包表記を使うと、 「s = [i+'*' for i in s]」 と書けるので、通常はこちらの方法を使ってリストの要素を変更します。
内包表記
リストの [ ] と for を組み合わせたリスト内包表記を使うと、 簡潔にリストの作成処理を書くことがができます。
「[i for i in range(5)]」とするとリスト [0, 1, 2, 3, 4] が得られます。 これに if 文を組み合わせると range で生成される値に条件を付け加えるリ ストに追加していくことできます。
また、リスト内包表記を2以上つ組み合わせると、それぞれのリスト内包表記 で生成されるリストを組み合わせたリストを作ることができます。
L = [i for i in range(5)] # 0≦i<5 の範囲 print(L) # [0, 1, 2, 3, 4] L = [i for i in range(5) if i%2 == 0] # if文を追加できる print(L) # [0, 2, 4] L = [i*2 for i in [1,2,3,4]] # リストの値変更 print(L) # [2, 4, 6, 8] L = [x+y for x in ['a','b','c'] for y in ['1','2','3']] # 2重のfor print(L) # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'] L = [] for x in ['a','b','c']: # リスト内包表記を使わない2重のfor for y in ['1','2','3']: L.append(x+y) print(L) # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
ディクショナリの { } と for を組み合わせたディクショナリ内包表記を使うと、 ディクショナリの作成処理を書くことがができます。
下記の例では整数を文字列に変換する str() 、文字コード(ASCIIコード)を 文字に変換する chr() を使用してディクショナリを作成しています。
各文字には整数値の文字コードが割り当てられており、それらは ord() で確認できます。 print(ord('A')) を実行すると 'A' の文字コードが 65 であることがわかります。
d = {str(i):i for i in range(3)} # 内包表記と str() を使ってディクショナリを作成 print(d) # {'0': 0, '1': 1, '2': 2} d = {chr(i):i for i in range(65,69)} # 内包表記と chr() を使ってディクショナリを作成 print(d) # {'A': 65, 'B': 66, 'C': 67, 'D': 68}
関数
関数の基本
関数の書式
特定の処理を同じプログラミム内で何度も実行する場合には関数を使います。 関数の実行は「呼び出し」とも呼ばれます。関数を定義すると、その関数はプ ログラム内から何度でも呼び出すことができるので、同じ処理を何度も書く手 間が省けプログラムが簡潔になります。
関数は「引数」と「戻り値」を持つことができます。引数は関数の呼び出し元 から関数へ情報を渡すためのもので、引数を使うとその値に応じて関数の処理 を変えることができます。戻り値は引数とは逆に、関数から呼び出し元に情報 を戻すためのもので、戻り値を使うと関数の呼び出し元に値を戻すことができ、 関数外でもその値を使用することができます。
関数の書式は以下のようになります。
def 関数名(引数) : # 関数定義 ... # 関数の文 ... # 関数の文 return 戻り値 # 戻り値の指定
関数の作成と呼び出し
関数は def で定義できます。
関数の呼び出しは「関数名(引数)」と書きます。引数のない関数では「関数名 ()」とします。
関数を呼び出すときにはその関数があらかじめ定義されている必要があるので、 関数の呼び出しはその関数の定義の下に書きます。
2乗を計算する関数の作成と呼び出しは以下のように行います。
def func(x): # 関数 func を 引数 x で定義 return x*x # 戻り値は x*x # 関数を呼び出すと 2*2 が計算されて値が戻る print(func(2)) # 4
引数が偶数なら10倍、奇数なら100倍する関数の作成と呼び出しは以下のよう に行います。
def func(x): # 関数 func を 引数 x で定義 if x%2 == 0: # 2で割ったときの余りが 0 かどうかをチェック x *= 10 # 余りがゼロのとき偶数なので10倍 else: x *= 100 # 余りがゼロでないとき奇数なので100倍 return x # 偶数は10倍される print(func(2)) # 20 # 奇数は100倍される print(func(3)) # 300
関数の引数へ代入
関数の呼び出しで引数が複数あるとき、呼び出しで並べた引数の順に関数の引 数に値が代入されます。このとき呼び出しでの引数の数と関数定義での引数の 数は一致させる必要があります。
関数の呼び出しで関数定義にある引数の変数名を使うと、呼び出しで引数の順 序に関係なく、関数で引数を直接指定してに値を代入することができます。
def func(a,b,c): print(a,b,c) # 引数の位置で値が決まる func(1,2,3) # 1 2 3 # 引数の名前で値が決まる func(b=2,c=3,a=1) # 1 2 3 # 引数の位置と名前で値が決まる func(1,c=3,b=2) # 1 2 3 # 引数の値を名前で決めた後に位置での設定はできない func(a=1,2,c=3) # エラー
関数の引数のデフォルト値
関数の定義では特定の引数に対して、呼び出しで値が指定されないときに使う デフォルト値(既定値)を設定できます。
関数の引数にデフォルト値が設定されている場合、関数呼び出しでその引数が 指定されていないときには関数内の処理でデフォルト値が使われ、指定されて いるときにはその値が使われます。
def func(a,b=2,c=3): # 引数 b, c にはデフォルト値が設定されいる print(a,b,c) # デフォルト値が設定されている変数の値は省略可能 func(1) # 1 2 3 # デフォルト値は上書きできる func(1,4) # 1 4 3 func(1,4,6) # 1 4 6 # 引数の名前を指定すると特定の引数を上書きできる func(1,c=6) # 1 2 6
下記の例でも関数での特定の引数にだけ値を代入することができます。また、 引き数名を明記することでプログラムが見やすくなることもあります。
def func(name='C',charge=0.,mass=12): print('name:',name,'mass:',mass,'charge:',charge) # 名前を指定して必要な箇所だけ上書きできる func(name='O',mass=16) # name: O mass: 16 charge: 0.0 func(charge=-0.2) # name: C mass: 12 charge: -0.2
関数内外での変数の扱い
関数と変数のスコープ
関数の内と外で同じ名前の変数を使うときに、変数の有効範囲を意識してプロ グラムを作る必要があります。この変数の有効範囲はスコープと呼ばれ、プロ グラム全体はグローバルスコープとなり、関数内のスコープはローカルスコー プとなります。
関数の外で作られた変数はグローバルスコープに属するため、グローバル変数 と呼ばれ、プログラム全体から参照できます。
Python では変数に値が代入されるとその変数が作られるので、関数内で変数 に値を代入すると、関数外に同じ名前の変数がある場合でも、その変数とは異 なる変数が作られます。この変数はローカルスコープに属するため、ローカル 変数と呼ばれ、参照できるのは作成された関数内のみです。
関数内でグローバル変数 a に値を代入する場合には、a がグローバル変数で あることを知らせるため、代入の前に「global a」を書く必要があります。
a = 2 # グローバル変数の a に代入 def func(x): a = x # ローカル変数の a に代入 # ローカル変数が優先して表示される print('in func a:',a) # in func a:1 func(1) # 関数外ではグローバル変数が表示される print('global a:',a) # global a:2 a = 2 # グローバル変数の a に代入 def func(x): global a # a はグローバル変数として使う a = x # グローバル変数の a に代入 # 関数内でもグローバル変数が表示される print('in func a:',a) # in func a:1 func(1) # 関数外でも関数内で変更されたグローバル変数が表示される print('global a:',a) # global a:1 a = 2 # グローバル変数の a に代入 def func(x): y = x + a # global a がなくてもグローバル変数の参照は可能 print(y) # 3 func(1)
関数での値変更: 不変性データ
関数に引数として渡された変数の値が、関数内で変更されたとき、その変更が 呼び出し元に反映されるかどうかは、引数となるデータが不変性であるか可変 性であるかによって変わります。
整数や文字列データは不変性なので関数内で値を変えても、呼び出し元の値は 変わりません。
def func(a,s): # 引数の整数と文字列は不変性 a = 2 # 関数内で値を変更 s = 'def' # 関数内で値が変わる print('in func: ',a,s) # in func: 2 def a = 1 s = 'abc' func(a,s) # 呼び出し元では値が変わらない print('global: ',a,s) # global: 1 abc
関数内で値を変更した不変性のデータの値を呼び出し元にも反映させたいとき は、戻り値で関数外の変数に値を代入します。
def func(a,s): # 引数となっている整数と文字列は不変性 a = 2 # 関数内で値を変更 s = 'def' # 関数内で値が変わる print('in func: ',a,s) # in func: 2 def return a, s # 値を戻り値で返す a = 1 s = 'abc' a, s = func(a,s) # 戻り値で値を変更 # 呼び出し元でも値が変わる print('global: ',a,s) # global: 2 def
関数での値変更: 可変性データ
リストやディクショナリは可変性なので関数内で値を変えると、呼び出し元で も値が変わります。
def func(L,d): # 引数となっているリストとディクショナリは可変性 L[0] = 4 d['a'] = 4 L = [1,2,3] d = {'a':1,'b':2,'c':3} func(L,d) # 関数内での代入で値が変わる print(L,d) # [4, 2, 3] {'a': 4, 'b': 2, 'c': 3}
可変性データの変更を呼び出し元に反映させたくない場合は、そのデータをロー カル変数にコピーし、ローカル変数の値を変更するようにします。
def func(L,d): # 引数となっているリストとディクショナリは可変性 L = L[:] # L の全要素をコピーしてローカル変数に上書き L[0] = 4 d = d.copy() # d の全要素をコピーしてローカル変数に上書き d['a'] = 4 L = [1,2,3] d = {'a':1,'b':2,'c':3} func(L,d) # 関数内ではコピーした変数に値を代入したので値が変わらない print(L,d) # [1, 2, 3] {'a': 1, 'b': 2, 'c': 3}
print による出力
print の使い方
print を使うと数値や文字などをそのデータ型に応じて表示できます。リスト やディクショナリを print で表示すると全ての要素を表示できるので簡単に 値を確認できます。
print(a,b) のように引数を複数指定したときには、空白で区切られた値が表 示されます。区切り文字のデフォルトは空白ですが print(a,b,sep=',') のよ うに sep で区切り文字を指定することもできます。
print での表示では、デフォルトで末尾に改行が追加され、指定した内容表示 した後に改行が行われます。末尾に追加される文字は end で指定でき、 print(a,b,end='') とすると改行されなくなります。
a = 1 b = 2 print(a,b) # 1 2 (通常の表示) print(a,b,sep=',') # 1,2 (カンマ区切りで表示) print(a,b,end='--') # (改行せずに末尾に -- を表示) print('next') # 1 2--next
データの型と識別値の表示
データや変数に入っているデータの型は type() で調べることができます。 Python の変数には型がないので print と type を使うと変数に入っているデー タの型を確認できます。
print(type(1)) # <class 'int'> (1 は整数) print(type(1.)) # <class 'float'> (1. は実数) L = [1,2,3] # print(type(変数)) で変数に入っているデータの型が表示される print(type(L)) # <class 'list'>
全てのデータにはそれぞれ異なる識別値が割り当てられており、その値は id() で調べることができます。 print と id を使うとデータの識別値を確認 できるので、異なる変数に入っているデータが同一かそうでないかがわかりま す。
a = 1 print(id(a)) # データ「1」 の識別値が表示される a = 2 print(id(a)) # データ「2」は「1」と異なる識別値となる L1 = [1, 2, 3] L2 = L1 print(id(L1),id(L2)) # L1 と L2 の識別値は同じ L2[0] = 0 # L2 の要素の値を変えると L1 の要素の値も変わる print(L1,L2) # [0, 2, 3] [0, 2, 3] L1 = [4, 5, 6] # L1 に別のデータを代入 print(id(L1),id(L2)) # L1 と L2 の識別値は異なる値となる
format を使った書式指定
print と format を組み合わせると、表示幅などの書式を指定できます。
format は print('1st {:4}, 2nd {:6.2f}'.format(10,23.456)) のように使 用し、このときの表示は「1st 10, 2nd 23.46」となります。この例では '1st' の後に整数値を4桁で表示し、'2nd' の後に実数値を全体幅6、小数点以 下2桁で表示しています。
format を使うと {} 内に指定した値が指定した書式で埋め込まれます。{ } は特殊文字として扱われるので、 { } をそのまま表示したいときには {{ }} を用います。
formatの書き方
format での { } は {置換フィールド:書式} のように書き「置換フィールド」 は format で与える引数の要素番号か変数名を指定し、「書式」では表示桁数 などの書式を指定します。
置換フィールドは print('{a} {1} {0}'.format(10,20,a=30)) のように書き、 このときの表示は「30 20 10」となります。{ } 内に整数値を書いた場合はゼ ロから始まる format の引数の並び番号、変数名を書いた場合は引数の変数名 で指定した値が使われます。
書式は{:6.2f}のようにコロン(:)の後に書きます。書式の書き方は文字列、整 数、実数それぞれで異なっており、表示幅や種類を指定できます。
文字列の書式
文字列での書式は print('{:3}'.format('a')) のように書き、この場合は表示 幅3の左詰めで「a_ 」が表示されます。(※空白は'_'で表示)
文字列で使える型は以下の通りです。
型 | 意味 |
---|---|
s | 文字列の表示 |
なし | 's'と同じなので通常は省略 |
整数値の書式
整数値での書式は print('{:3}'.format(12)) のように書き、この場合は表示 幅3の右詰めで「_12」が表示されます。(※空白は'_'で表示)
整数値で使える主な型は以下の通りです。
型 | 意味 |
---|---|
b | 2進数表示 |
c | 文字コードによる1文字表示 |
d | 10進数表示 |
x | 16進数表示 |
, | カンマ(,)で3桁区切り |
なし | 'd'と同じなので通常は省略 |
実数値の書式
実数値での書式は print('{:6.2f}'.format(23.456)) のように書き、この場 合は表示幅6の右詰め、小数点以下2桁で「_23.46」が表示されます。(※空白 は'_'で表示)
実数値で使える主な型は以下の通りです。
型 | 意味 |
---|---|
f | 小数点数表記(デフォルト精度6桁) |
e | 指数表記(デフォルト精度6桁) |
g | 桁に応じて f もしくは e |
, | g で実部をカンマ(,)3桁区切り |
% | f で100倍したパーセント表記 |
なし | g とほぼ同じ |
print('{a} {1} {0}'.format(10,20,a=30)) # 30 20 10 print('{:3}'.format('a')) # a__ print('{:3}'.format(12)) # _12 print('{:03}'.format(12)) # 012 (03とするとゼロ詰めとなる) print('{:6.2f}'.format(23.456)) # _23.46 print('{:9.2e}'.format(23.456)) # _2.35e+01 print('{:,}'.format(12345.6789)) # 12,345.6789 print('{:.2%}'.format(0.08)) # 8.00% # ※空白は'_'で表示
f文字列を使った書式指定
Python 3.6 以降ではf文字列 (f-string) が使用でき format よりも簡単に書 式指定ができます。
f文字列は f'{変数名:書式}' のように書き、 a = 23.456 の場合 print(f'{a:6.2f}') で「_23.46」が表示されます。(※空白は'_'で表示)
f文字列の { } 内には式も書けるので a = 1 および b = 2 の場合 print(f'{a+b}') で「3」が表示されます。
f文字列で使用する書式は format と同じです。
a = 1 b = 2 print(f'{a+b}') # 3 s = 'a'; print(f'{s:3}') # a__ a = 23.456 print(f'{a:6.2f}') # _23.46 print(f'{a:9.2e}') # _2.35e+01 # ※空白は'_'で表示