Python経験ゼロからPython試験を受けたときに必要知識をまとめたものを公開しておきます。だいたい要点は押さえられています。これから受験される方は参考にしてください。
Pythonの学習方法
体系立ててPythonを学びたい場合は動画学習をおすすめします。以下におすすめの動画をまとめていますので参考にしてください。
Pythonの効率的な試験対策方法
私がPython試験に合格した際に、練習用に作成したWebアプリです。
試験後、より効率的な対策ができるよう問題内容も見直しました。ご自由にお使いください。
Pythonとは
Pythonはインタープリタ言語
プログラムはC言語、Java、JavaScript、Ruby、PHPなどいろいろな言語で書かれますが、コンピュータはこれらの言語で書かれたままの状態では理解できません。必ずコンピュータが理解できる”機械語”に変換してから読み込みます。
インタープリタ言語は、コードを実行する際に1行ずつ機械語に翻訳していく言語です。コンパイル言語は、まず全てのコードを機械語に翻訳してから一気に実行する言語です。
インタープリタ言語はプログラムをコンパイルなしですぐに実行できるというメリットがある一方、一行一行翻訳しながら実行するためにコンパイラ言語に比べて実行速度は遅くなります。
インタープリタは対話的にも使えます。
Pythonでプログラムを書く際のグルーピングはインデントを使う
Pythonではインデントでグルーピングします。
x = 3
if x == 3:
print("True!") #ifのブロック
なお、PEP8(Pythonコーディング規約)では「インデントは半角スペース4つで統一すること」とされています。
Pythonで変数や引数の宣言は不要
Pythonでは変数や引数の宣言が不要です。正確には、変数に値を代入したときに変数の宣言が自動的に行われます。
以下のように、変数に値を代入していない状態で変数を呼び出すとエラーになります。
print(hoge)
#⇒NameError: name 'hoge' is not defined
Pythonインタープリタ周辺のこと
プライマリプロンプト(>>>)が出ている状態でインタープリタを終了させる方法
インタープリタを終了させる方法は以下の2通りがある。
- WindowsではCtrl+Z、UNIXではCtrl+D
- quit()
プライマリプロンプト(>>>)が出ている状態で、WindowsではCtrl+Z、UNIXではCtrl+Dを押下することでインタープリタを終了することができる。また、「quit()」と入力することでもインタープリタを終了することができる。
セカンダリプロンプトについて
プライマリプロンプト(>>>)の継続行としてセカンダリプロンプト(…)が出てくる。記号に注意。
インタープリタでコマンド行編集機能を使えるか使えないかの判定方法
Ctrl+Pでピープ音が鳴れば使える、^Pと表示されると使えない。
インタープリタを起動するコマンド
インタープリタは下記のコマンドでも起動できる。
python -c command [arg] ...
Pythonプログラム実行時に、コマンドラインで引数を指定し、プログラム内で引数を受け取る方法
Pythonプログラム実行時にコマンドラインで引数を指定する場合、標準ライブラリであるsysモジュールのargvを利用する。argvはスクリプトに渡されたコマンドライン引数が格納されたリストとなる。
#sample.py
import sys
args = sys.argv
print(args)
コマンドライン
$ python sample.py hoge
実行結果
['sample.py', 'hoge']
argv[0]にはスクリプト名、argv[1]には第一引数、argv[2]には第二引数、argv[3]には第三引数…が格納される。
Pythonのデフォルトのエンコーディングについて
Pythonの標準文字コード(バージョン3.x以降)は UTF-8です。
「文字コード」とは、パソコンが文字を扱えるよう、文字をあらかじめ決めたコードに置き換えたもの。デフォルトエンコーディングはファイル先頭に以下の記述をすることで変更することができる。
# -*- coding: cp1252 -*-
バイトコンパイル
インタプリタ型言語なのになぜ「コンパイル」?
Pythonはインタプリタ型言語なのになぜ「コンパイル」なのか?これは、Pythonは毎回機械語に翻訳されて実行されるが、事前にコンパイルしておくことで、この毎回かかる無駄な時間を短縮できるというもの。実行開始までの速度を短縮できるというだけで、処理速度が速くなるわけではない。
コマンド
バイトコンパイル時のコマンドの構文は下記。sample.pyのところは対象ファイル名となる。
python -m compileall sample.py
バイトコンパイルを実行すると、pycacheディレクトリが作成され、その中に.pycファイルが生成されているのが確認できる。
エスケープシーケンス、四則演算、文字列操作
エスケープシーケンス
s = 'fukuoka\saga\nagasaki'
print(s)
print(len(s))
実行結果
#\nによって改行されてしまう、また改行コード\nは一文字としてカウントされる
fukuoka\saga
agasaki
20
raw文字列ではバックスラッシュ( Windows 環境では円記号)をエスケープ用の文字ではなく単なる文字として扱う。
s = r'fukuoka\saga\nagasaki'
print(s)
print(len(s))
実行結果
fukuoka\saga\nagasaki
21
例をもう一つ。
s='don\'t'
print(s)
print(len(s))
実行結果
don't
5
四則演算と数値型
割り算
a=19/3
print(a)
a=19//3
print(a)
a=19%3
print(a)
実行結果
6.333333333333333
6
1
かけ算
a=3*3
print(a)
a=3**3
print(a)
実行結果
9
27
あらためて型混在の場合の注意点
#float型とint型が混在する場合の結果はfloat型
a=7.0/2
print(a)
#引き算の場合も同様
a=7.0-2
print(a)
#割り算の結果は常にfloat型(整数同士であっても)
a=8/2
print(a)
実行結果
3.5
5.0
4.0
文字列の乗算
a= 'foo'*3+'bar'
print(a)
実行結果
foofoofoobar
文字列操作
word='abCDefGHijKLmn'
print(word[0])
print(word[6])
#注意(index2番目の要素から、位置9まで)
print(word[2:9])
print(word[2:])
print(word[-2:])
#注意(-2に位置するmは含まれない)
print(word[:-2])
実行結果
a
G
CDefGHi
CDefGHijKLmn
mn
abCDefGHijKL
#文字列は書き換え不能(イミュータブル)
word='abCDefGHijKLmn'
word[4] = 'z'
実行結果
TypeError: 'str' object does not support item assignment
リスト関連
リスト要素の範囲選択
list_a = ['apple', 'banana', 'orange', 'grape', 'melon']
print(list_a[2:4])
print(list_a[-1:4])
print(list_a[-2:4])
print(list_a[-3:4])
実行結果
['orange', 'grape']
[]
['grape']
['orange', 'grape']
リスト要素の置換
※文字列と違って書き換え可能
※挿入ではない。
list_a = ['apple', 'banana', 'orange', 'grape', 'melon']
list_a[4] = 'maskmelon'
print(list_a)
実行結果
['apple', 'banana', 'orange', 'grape', 'maskmelon']
リスト要素の追加
appendで末尾に追加される。
list_a = ['apple', 'banana', 'orange', 'grape', 'melon']
list_a.append('kiwi')
list_a.append('kiwi2')
print(list_a)
#2つ同時にappendはできない(コード省略)
実行結果
['apple', 'banana', 'orange', 'grape', 'melon', 'kiwi', 'kiwi2']
リストの範囲削除
list_a = ['apple', 'banana', 'orange', 'grape', 'melon']
list_a[1:3]=[]
print(list_a)
実行結果
['apple', 'grape', 'melon']
リストの長さ
list_a = [[2, 3, 4],['apple', 'banana', 'orange']]
print(len(list_a))
実行結果
2
リストから特定の値を取り出す
list_a = [[2, 3, 4],['apple', 'banana', 'orange']]
print(list_a[1][1])
実行結果
banana
リストから特定の値を取り出す2
list_a = [[2, 3, 4], ['apple', 'banana', 'orange', [10, 20, 30]]]
print(list_a[1][3][1])
実行結果
20
rangeまわり
rangeを使ってfor文を回すのがPython風らしい。ということでrangeの練習。
rangeの挙動範囲を確認
終了値のみ指定
list_a = range(5)
print(list_a)
実行結果
range(0,5)
for文で回す。
for i in range(5):
print(i, end=',')
実行結果
0,1,2,3,4,
#0から始まり、終了値は含まないことに注意
開始と終了を指定
for i in range(1,10):
print(i,end=',')
実行結果
1,2,3,4,5,6,7,8,9,
#開始値から始まり、終了値は含まないことに注意
一定間隔で(ステップ指定)
#10は含まないことに注意、間隔3は開始値1に3加えていく計算
for i in range(1,10,3):
print(i,end=',')
実行結果
1,4,7,1,5,9,
マイナスの例
for i in range(0,-20,-3):
print(i,end=',')
実行結果
0,-3,-6,-9,-12,-15,-18,
rangeでリストを作成
#rangeでlistを作成
a = list(range(1,10))
print(a)
実行結果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
その他サンプル1
print('1~20までを加算する')
cnt = 0
for i in range(1,21):
cnt = cnt + i
print(cnt)
実行結果
1~20までを加算する
1
3
6
10
15
21
28
36
45
55
66
78
91
105
120
136
153
171
190
210
その他サンプル2
print('1~100のうちかけたら256になる組み合わせ')
for i in range(1,101):
for j in range(1,101):
if i*j == 256:
print(i,j)
実行結果
4 64
8 32
16 16
32 8
64 4
その他サンプル3
#余りが1であったらリストに追加(タプルとして追加)
list_a = [] #初期化
for i in range(1,11):
for j in range(1,11):
if i%j==1:
list_a.append((i,j))
print(list_a)
実行結果
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (3, 2), (4, 3), (5, 2), (5, 4), (6, 5), (7, 2), (7, 3), (7, 6), (8, 7), (9, 2), (9, 4), (9, 8), (10, 3), (10, 9)]
関数まわり
基本形
フィボナッチ数列の例
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=',')
a, b = b, a+b
print()
fib(2000)
実行結果
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,
関数の読まれる順序
コードは上の行から順に解釈されており、def keisan(arg=i)で10が格納されていて、keisan()で呼び出されたときに実行される。
i = 10
def keisan(arg = i):
print(arg**2)
i = 2
keisan()
実行結果
100
ちなみに当然ながらprint(arg**2)
の箇所をprint(i**2)
としたら関数呼び出し直前にiには2が格納されているので、出力は4となる。
i = 10
def keisan(arg = i):
print(i**2)
i = 2
keisan()
実行結果
4
値を保持する関数の例
def f(i, list_a=[]):
list_a.append(i)
return list_a
print(f(1))
print(f(2))
print(f(3))
実行結果
[1]
[1, 2]
[1, 2, 3]
値を保持させない関数の例
def f(i, list_a=None):
if list_a == None:
list_a = []
list_a.append(i)
return list_a
print(f(1))
print(f(2))
print(f(3))
実行結果
[1]
[2]
[3]
引数にデフォルト値を設定すると
デフォルト値を設定すると、引数を省略できる。引数を省略しなかったらその値で初期値が上書きされる。
def kansuu(arg_a, arg_b=2):
print(arg_a * arg_b)
kansuu(2)
kansuu(2,3)
実行結果
4
6
キーワード引数について
- キーワード指定していない引数(位置引数)は入力必須。
- キーワード引数は位置引数の後にこないといけない。
- キーワード引数同士は順序が入れ替わってもOK。
def kansuu( name, height=201, weight=80 ):
print(name,height,weight)
kansuu('John')
kansuu('Mark', weight=95)
kansuu(height=198, weight=95)
実行結果
John 201 80
Mark 201 95
TypeError: kansuu() missing 1 required positional argument: 'name'
リスト内包表記
リスト内包表記を使うことで、リスト、タプル、辞書を手軽に作成できる。その名のとおりリストに内包する形で表記するもの。
リスト内包表記じゃない書き方
list_a = []
for i in range(0,10):
list_a.append(i**2)
print(list_a)
実行結果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
リスト内包表記
list_a = [i**2 for i in range(0, 10)]
print(list_a)
実行結果
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
if文を含む場合
まずはリスト内包表記じゃない書き方
list_a = []
for i in range(0,10):
if i%2==0:
list_a.append(i**2)
print(list_a)
実行結果
[0, 4, 16, 36, 64]
リスト内包表記の書き方
list_a = [i**2 for i in range(0, 10) if i%2==0]
print(list_a)
実行結果
[0, 4, 16, 36, 64]
位置引数とキーワード引数の特殊パラメータ
関数の位置引数とキーワード引数については、可読性とパフォーマンスのために特殊パラメータが用意されている。
位置引数とキーワード引数とは
位置引数(位置専用引数)
- 位置の場合、引数の順序が重要でありキーワードで引数を渡せない。
- / の前に配置されたものは位置専用引数と認識される。
- 関数定義に / がない場合、位置専用引数はない。
- / の後の引数は、 位置orキーワード 、もしくはキーワード専用 。
キーワード引数(キーワード専用引数)
- *の後に配置されたものはキーワード専用引数と認識される。
サンプルコードから読み解く
指定なしの場合
#呼び出しに制限を設けない、引数は位置orキーワードで渡される
def standard_arg(arg):
print(arg)
standard_arg(2)
standard_arg(arg = 2)
standard_arg(art = 2)
実行結果
2
2
TypeError: standard_arg() got an unexpected keyword argument 'art'
当然ながらキーワード名は正しく指定しないとエラーとなる。
位置専用引数
# / が関数定義にあるので、引数は位置専用
def pos_only_arg(arg, /):
print(arg)
pos_only_arg(3)
pos_only_arg(arg = 3)
実行結果
3
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'
キーワード専用引数
# * が関数定義にあるので、引数はキーワード専用
def kwd_only_arg(*, arg):
print(arg)
kwd_only_arg(arg = 3)
kwd_only_arg(3)
実行結果
3
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
位置専用引数とキーワード専用引数の混在
def combined_example(pos_only, /, standard, *, kwd_only):
print(pos_only, standard, kwd_only)
#どちらもいけるはず
combined_example(1, 2, kwd_only = 3)
combined_example(1, standard = 2, kwd_only = 3)
実行結果
1,2,3
1,2,3
ラムダ式
lambda(ラムダ式)で名前を持たない無名関数を作成することもできる。
関数(def)で書くまでもないちょっとした処理をインラインで書くために使われることが多い。
def kansuu(n):
return lambda x: x + n
f = kansuu(100)
print(f(1))
実行結果
101
pairs = [(3, 'three'), (2, 'two'), (5, 'five'), (1, 'one'), (4, 'four')]
pairs.sort(key=lambda pair: pair[0])
print(pairs)
pairs.sort(key=lambda pair: pair[1])
print(pairs)
実行結果
[(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five')]
[(5, 'five'), (4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
関数defとの対比でみるとわかりやすい。
defの場合
def tasu(a, b=1):
return a + b
print(tasu(6, 7))
print(tasu(6))
実行結果
13
7
lambdaの場合
tasu_lambda = lambda a, b=1: a + b
print(tasu_lambda(6, 7))
print(tasu_lambda(6))
実行結果
13
7
zip関数
zip関数はリストやタプルなどの要素をまとめる関数。forループとの組み合わせで有効活用できるっぽい。
2つのリストをまとめる例
subjects = ['English', 'Science', 'Music']
scores = [84, 95, 70]
for subject, score in zip(subjects, scores):
print(subject, score)
実行結果
English 84
Science 95
Music 70
3つのリストをまとめる例
subjects = ['English','Science','Music']
scores = [84, 95, 70]
averages = [88, 71, 75]
for subject, score, average in zip(subjects, scores, averages):
print(subject, score, average)
実行結果
English 84 88
Science 95 71
Music 70 75
少ない要素数のリストがある場合の挙動
subjects = ['English','Science','Music']
scores = [84, 95] #少ない
averages = [88, 71, 75]
for subject, score, average in zip(subjects, scores, averages):
print(subject, score, average)
実行結果
English 84 88
Science 95 71
#⇒少ない要素数の項目にあわせられる
glob関数
glob関数でサブフォルダを含めてファイルを検索できる。
glob関数の使い方
dドライブ直下で拡張子が.pdfのものを抽出したいとする。
import glob
print(glob.glob('d:\*.pdf'))
実行結果
['d:\\a.pdf', 'd:\\b.pdf', 'd:\\c.pdf']
glob関数でサブフォルダまで検索
以下のような指定の仕方だと、dドライブ配下のすべてのサブフォルダまで検索できる。\**
の部分の変更だけでなく、recursive=True
とする必要がある。(デフォルトではrecursive=Falseとなっている)
import glob
print(glob.glob('d:\**\*.pdf'), recursive=True)
実行結果
['d:\\a.pdf', 'd:\\b.pdf', 'd:\\c.pdf', 'd:\\sub\e.pdf', 'd:\\sub\f.pdf']