こんにちは。薬学長です。
今回は、Pythonの基本講座➃ということで始めていきましょう。
14. 制御文(if文)
if文は、渡された値の真偽を評価し、真の場合は実行され、偽の場合は実行されない式です
if評価式:
式
の形で記載されます。
pythonでは、以下の値がFalseとして認識されます
Falseとして認識されるもの:None,False,0,”,空リスト,空辞書,空タプル,空セット
■bool()が定義されているクラスで、Falseが返されるもの
変数.bool()= bool(変数)
if文を複数重ねる場合は、elif や elseを利用します
等価性:<,<=,>,>=,!=,==,not
if 評価式1:
式
#評価式1が正の場合実行
elif 評価式2:
式
#評価式1が偽で、評価式2が正の場合実行
else:
式
#評価式1も評価式2も偽の場合実行
and or not
複数の条件式を評価する場合、and orを利用します。
また、条件式の否定としてnotが利用されます
➀条件式1 and 条件式2とすると、両方が正しい場合に実行されます。
➁条件式1 or 条件式2とすると、どちらか一つが正しい場合実行されます。
➂not 条件式とすると、条件式が誤っている場合に実行されます。
all, any 関数
if文でallとanyを利用すると処理の記載が楽になります。
all : allはオブジェクトの中が全てTrueの場合に処理をする
if all(反復可能オブジェクト):
#リスト、タプル等、forinでループできる変数を入れます。
処理
any : anyはオブジェクトの一部がTrueの場合に処理をします。
if any(反復可能オブジェクト):
15. ループ文(while)
ループでは、複数回同じコードを実行します。pythonではforやwhileを用いてループを実現します。
for制御式
式
#ループ内の式が実行される
range関数(for i in range()として利用)
range(5):
※01234を返す
range(2,6):
※2345を返す
range(0,10,3):
※0,3,6,9
for i in range(5):
print(i)
#01234を表示
リストのループ
sample=[‘A’,‘B’,‘C’]
for s in sample:
print(s)
#ABCを表示
enumerate関数:
※配列の中の値とインデックスを同時に取得する
sample=[‘A’,‘B’,‘C’]
for index , value in enumerate(sample):
print(index)
#012を表示
print(value)
#ABCを表示
zip関数:
※二つの配列の中の値を同時に取得する
for a,b in zip(list1,list2):
while:
※whileの中の式がTrueであるうちは処理を実行する
count=0
while count < 10:
print(count)
count += 1
ループ内でのcontinue,break,elseの使い方
continue:
※ループ内にcontinueがあると処理が一度飛ばされます
break:
※breakが実行されるとループの外に処理が出ます
for i in range(8):
if i==5:
continue
#iが5の時は、処理が飛ばされますi=6の場合の次の処理に移ります。
breakの場合は処理が終了してループの外に出ます
print(i)
else:
※ループの外に出た際に実行されます(breakでループを抜けた場合には実行されません)
for i in range(10):
print(i)
else:
print(‘ループ終了’)
#ループ終了後実行されます
※セイウチ演算子 := イコールの前に「:」コロンをつけた演算子
セイウチ演算子とは変数の代入と変数の使用を同時に実行できるという特徴を持っています
if(n:=10)>5:
#nに10を代入するのとn>5の比較を同時に実行している
print( ‘nは5より大きい’)
一番よく使うパターンは、while文で使用することが多いです。
n=0
while(n:= n + 1) < 10:
print(n)
n=1
while n < 10:
print(n)
n += 1
例外処理(tryとexcept))
例外処理:
※実行時に発生するエラー(実行時エラー)を制御して処理を行う
try:
処理
except
エラー名
例外発生時の処理
例文)
try:
a = 10 / 0
except ZeroDivisionError:
print(‘例外処理’)
FileNotFoundError:
※プログラムで指定されたファイルが見つからないエラー
IndexError:
※配列などで指定したインデックスに値が存在しないエラー
TypeError:
※型に関するエラー
ZeroDivisoinError:
※0で割ろうとしたことによるエラー
Exception:
※すべての例外
例外処理(try, except,else,finally))
例外処理を複数つないだもの
fruits = [‘apple’,’orange’,’pain’]
count = 12
try:
fruit = fruits[2]
print(fruit + count)
except IndexError as e:
print(‘配列に存在しないインデックスを指定した場合’)
except TypeError:
print(‘文字列型+数値型等、型の誤ったものと計算した場合などに実行’)
except Exception:
print(‘全ての例外をキャッチ’)
else:
処理
finally:
処理
else,finally:例外処理後に実行される
else:
※例外が発生しなかった場合に実行され、例外が発生した場合には実行されない
finally:
※例外が発生した場合にも、発生しなかった場合にも実行される
例外を返す(raise)
def devide(a,b):
if(b==0):
raise ZeroDivisionError(‘bを0に設定しないでください’)
#raiseをすると呼び出し元にメッセージと共に、例外を返すことができます。
else:
returna/b
try:
result = devide(10,0)
#関数を呼び出した結果、ZeroDivisionErrorが返ってきます。
except ZeroDivisionError as e:
print(‘{}:{}’.format(type(e),e))
#ZeroDivisionErrorが発生したため、:bを0に設定しないでくださいと表示
16. 関数
関数とは一連の処理を1つにまとめたものです。
pythonの関数は以下のように定義します。
def 関数名():
処理
def print_hello():
#関数の定義
print(“Hello”)
#関数の処理
print_hello()
#関数の呼び出し、Helloが表示されます。
関数に引数を与えるには
def 関数名(arg1,arg2):
def num_max(a,b):
if a>b:
return a
else:
return b
num = num_max(10,20)
#大きい20が返ってきます
num = num_max(b=20,a=10)
#引数を直接指定することもできます
関数のデフォルト値の指定
deffunction(arg1,arg2=100):
可変長引数:場合に応じてその都度、引数の長さが変わるもの
可変長のタプル:*arg1のように「*」を1つつける
可変長の辞書 :**arg2のように「**」を2つつける
defspam(arg1,*arg2):
print(“arg1={},arg2={}”.format(arg1,arg2))
#arg1とarg2を表示します。
print(type(arg2))
#<class’が表示され、arg2がタプルであることがわかります。
spam(3,4,5,5)
#1つ目の引数はarg1,残りはarg2に4,5,5がタプルとして挿入され、”arg1=3,arg2=(4,5,が表示されます
defspam(arg1,**arg2):
print(“arg1={},arg2={}”.format(arg1,arg2))
#arg1とarg2を表示します。
print(type(arg2))
#<classdictが表示され、arg2が辞書型であることがわかります。
spam(3,arg3=5,arg4=6)
#”arg1=3,arg2={‘arg3′:5,’arg4’:が表示されます。
複数の返り値
return a,b
17. グローバル変数
変数には利用できる領域(名前空間)があります。
別の名前空間の変数を更新することができない場合があります。
例えば、以下のように関数の中から関数の外の変数を書き換えることができません。
globalを使わない場合
def printAnimal():
animal=’cat’
#ここで宣言した変数animalは関数の外で宣言したanimal(‘dog’)とは
異なる変数として扱われ、この関数内のみで有効な変数です。
print(animal)
#print(animal)でcatが表示されます。
animal=‘dog’
#関数外の変数
print Animal()
print(animal)
#このprintでは、関数の外で有効なanimal(‘dog’)が表示されます。
上から実行した結果、cat,dogと表示されます。
globalを使った場合
変数の名前空間を広げることができます
def printAnimal():
global animal
#animalの前に、globalを付けて、global変数として宣言すると
このanimalは関数の外までスコープが広がります。
同名の変数が関数の外に存在する場合は、同じ参照先になります
animal=‘cat’
#このanimalはグローバル変数のため、関数の外のanimalの値も変更されます。
print(animal)
#print(animal)でcatが表示されます。
animal=’dog’
#関数外の変数
printAnimal()
print(animal)
#関数実行時にanimalの値はcatに書き換えられているため、ここでcatと表示されます。
18. inner関数とノンローカル変数
pythonでは、関数の内部に関数を書くことができます。これをinner関数と言います。また、ノンローカル変数として宣言すると内側の関数から外側の関数で宣言された変数を書き換えられるようになります。
Inner関数の書き方
def outer():
def inner():
#inner関数の処理
#外の関数から、inner関数を呼び出す等を行う。
nonlocal変数を用いたinner関数の定義
defouter():
outer_value = ‘外’
#外側の変数outer_valueに外という文字が代入されます。
def inner():
nonlocal outer_value
#nonlocalと宣言することで、外側の関数の変数であるouter_valueを
変更できるようになります。
inner_value = ‘内’
#内側の関数の変数のinner_valueに内という文字が代入されます。
outer_value = ‘内側で変更’
#outer_valueはnonlocalとして宣言しており、このouter_valueを用いて
外側の関数の変数outer_valueに文字列内側で変更が代入されます。
inner()
#inner関数を実行します。
return outer_value
#returnouter_valueこの場合、文字列内側で変更が返されます
value=outer()
#関数outerを呼び出して、その返り値内側で変更をvalueに代入します。
print(value)
#value(‘内側で変更’)を表示します。
inner関数の用途
➀外の関数の外からアクセスできないような関数を作成する
➁関数の中で同じ処理が何度も発生する場合に、一つにまとめる
➂デコレータ関数(後述)を作成する
19. ジェネレータ関数
ジェネレータ関数は以下のようにyieldを用います。
def func()
yield 〇〇
➀ジェネレータ関数を宣言して実行すると、yieldの部分で処理がストップし、yieldの〇〇に記載された値(配列、辞書等オブジェクト)が呼び出され元に返されます。
➁その後、再度ジェネレータ関数を呼び出すと、yieldの部分から処理がスタートし、yieldの部分でストップします。
➂プログラムが終了するまで、何度もジェネレータ関数を呼び出すことができます。(その度に、yieldからスタート、yieldで終了します)
def generator(max):
#ジェネレータ関数の宣言
print(“generatercreated”)
n=0
while n < max:
yield n
#呼び出し元にnを返し処理がストップ
print(“yield called”)
n+=1
gen=generator(10)
#ジェネレータの作成、この時点では処理は走りません。
a = next(gen)
#generatorを呼び出します。generator createdと表示されて、
yieldの部分でとまり、yeild nのn(この場合0)が値として返ってきます。
print(a)
#0が表示されます。
ジェネレータ関数のメソッド
send():
※yieldで停止している箇所に値を送ります。
throw():
※指定した例外が発生して処理が終了させます。
close():
※ジェネレータを正常終了させます。
gen.send(10)
#yieldの部分に、sendを創出し、yieldの部分の値が10となって処理が進む。
for v in gen:
print(v)
if v > 2:
gen.throw (ValueError(“InvalidValue”))
#ValueErrorを送出して処理を終了します。
gen.close()
#close()をするとジェネレータ処理が強制終了して、以後、generatorは StopIterationと表示されて利用できなくなります。
サブジェネレータ
pythonでは、ジェネレータからジェネレータを呼び出すことができます。
呼び出した時の呼び出し元がジェネレータ、呼び出し先がサブジェネレータと言います。yield fromと記述して、ジェネレータからサブジェネレータを呼び出します。
➀呼び出し先のサブジェネレータからさらに別のジェネレータを呼び出すこともできます
➁サブジェネレータにreturnを追加することで、呼び出し元ジェネレータに値を返すことができます。
➂サブジェネレータでyieldを実行すると一番最初の呼び出し元に値を返します。
ジェネレータはどういう場面で使用するのか?
ジェネレータはメモリ使用量を削減するために使われます。
例えば以下の場合、実行される結果は同じですが利用されるメモリ使用量が違います。
list_a == [0,1,2,3,4,5,6,7,8,9]
for i in list_a:
print(i)
def num(max):
#generatorを定義
i = 0
while i < max
yield i
i += 1
for x in num(10):
#generatorを呼び出し
print(x)
#0から9まで表示
generatorが一番多く出番となるのは、何らかのDBから大量のデータを抽出するときです。DBから対象に取得する場合、大変メモリ消費します。
この場合、generatorを使うと使用するメモリをほぼ0にすることができます
(ただし、generatorの方が処理は遅いといい欠点があります)
20. 高階関数
pythonでは、関数もオブジェクトの一つにすぎないため変数として扱うこともできます。また、関数を他の関数の引数として渡したり、返り値として扱うこともできます。関数を引数にしたり、返り値にする関数を高階関数と言います。
➀関数を変数のように扱う
def print_hello():
print(“hello”)
var = print_hello
#変数varに関数をオブジェクトとして代入します。
var()
#このように変数に()を付けると関数が呼び出され、helloが表示されます。
var2=[‘apple’,’orange’,print_hello]
#配列の3番目(インデックスだと2)にprint_helloをオブジェクトとして、
入れておきます。
var2[2]()
#配列のインデックス2のprint_helloを呼び出すと、helloと表示されます。
➁引数、返り値に関数を利用するやり方
def print_world(msg):
print(“{}world”.format(msg))
def print_konnichiwa():
print(“こんにちは”)
def print_hellofunc):
func(“hello”)
#引数funcを関数のように利用します。
return print_konnichiwa
#関数print_konnichiwaを返します。
var = print_world
#変数varに関数print_worldをオブジェクトとして代入します。
a = print_hello(var)
#関数print_helloの引数をprint_worldにして、呼び出します。
#func(“hello”)がprint_world(“hello”)になり、関数で”hello world”が表示されます。
#また、aには、関数print_konnichiwaが格納されます。
a()
#関数print_konnichiwaが実行され、”こんにちは”と表示されます。
21. lambda式
#ifを1行で表して代入する
x = 0 if y > 10 else 1
pythonで1行で終わるような関数を用いる場合には、lambda式という無名関数を用いることがよくあります。lambda式は以下のように書きます。
lambda引数:
※返り値
lambda_a = lambdax: x * x
#aに無名関数のオブジェクトを代入します。
↓
def func(x):
return x * x
res = lambda_a(12)
#引数を12として、無名関数を実行します。戻り値は、x * xの144が返ってきます。
print(res)
#144が表示されます。
lambda_b = lambda x,y,z = 5: x * y * z
#lambda式で、複数の引数を取り、一部の引数にデフォルト値を入れて定義します。
print(lambda_b(3,4))
#x=3,y=4として関数が実行され、60が表示されます。
➀条件式を用いたlambda
c = lambda x , y: y if x < y else x
#x<yの場合yを返し、それ以外はxを返す
22. 再帰
再帰とは、関数から自分の関数を呼び出すことです。
def sample(a):
if a < 0:
return
else:
print(a)
sample(a-1)
※フィボナッチ数列
1と2のとき:1
3以上のとき:直前の二つの数値の和1,1,2,3,5,8,13,…とする数列
def fib(n):
if n < 3:
return 1
else:
return fib(n-1) + fib(n-2)
23. リスト内包表記
ループと条件を使って、1行でリストを作成する方法(リスト内包表記)
変数名 = [式 for変数inリスト(if条件式)]
new_list = []
for x in list_a:
new_list.append(x)
↓
new_list = [x for x in list_a]
new_list = []
for x in list_a:
if type(x) == int:
new_list.append(x)
↓
new_list = [x * x for x in list_a if type(x) == int]
ジェネレータを返すには、以下のように宣言します
x=(リスト内包表記)
value = [x for x in range(10000)]
#リスト
tup = tuple(x for x in range(10000)
#タプル
gen = (x for x in range(10000))
#ジェネレータ
set = {x for x in range(10000)}
#セット
24. デコレータ関数
Pythonの場合、@関数名と関数の前につけることで、デコレータ関数を利用します。
デコレータは、関数オブジェクトを引数にとって引数にとった関数に実行時に変更を加えます。デコレータは関数間で、ある処理を共通に利用したい場合によく用いられます。
def my_decorator (func):
#デコレータ関数
def wrapper(*args,**kwargs)
print(‘*’ * 100)
func(*args, **kwargs)
print(‘*’ * 100)
return 1
return wrapper
@my_decorator
#デコレータ関数の利用
def func_a(*args,**kwargs)
pass
@my_decorator
#デコレータ関数の利用
def func_b(*args,**kwargs)
pass
func_a
def wrpper(args,kwargs)
print(‘*’ * 100)
func_a(*args,**kwarg)
print(‘*’ * 100)
return 1
以上です。大変お疲れ様でした。今回の講義では制御文を行ってきました。
次はオブジェクト指向プログラミングをやっていきます!