仕事上、早々にを使えるようにしないといけないため、
を基に学んでいく。
前回
2. Python組み込みのデータ構造と関数、ファイルの扱い
2.2 関数
において関数はキーワードで宣言してキーワードで戻す。
def my_func(x,y,z=1.5): if z>1: return z * (x + y) else: return z / (x + y) a = my_func(5,6, z = 0.7) b = my_func(3.14,7, z = 3.5) c = my_func(10,20) print(a) print(b) print(c)
2.2.1 名前空間、スコープ、ローカル関数
関数は、グローバルスコープとローカルスコープという2つの異なるスコープの変数にアクセスできる。
関数内で定義された変数は基本的にローカルである。
# 複数の値を返す def f(): a = 5 b = 6 c = 7 return a,b,c a,b,c = f() print(a,b,c)
スコープ外の変数に代入するには、キーワードを使って宣言しなければならない。
a = None def bind_a_variable(): global a a = [] bind_a_variable() print(a)
2.2.2 複数の値を返す
# 複数の値を返す def f(): a = 5 b = 6 c = 7 return a,b,c a,b,c = f() print(a,b,c)
2.2.3 関数はオブジェクトである
の関数はオブジェクトであるため、他言語では実装が難しいような多くの概念を簡単に表現することができる。
たとえばデータクリーニングの一環として以下の文字列のリストにいくつかの変換処理を施すことを考える。
########################################################## ### 以下の文字列のリストを適正にデータクレンジングする ### ########################################################## states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?'] # 1. 正規表現の組み込みライブラリreをを用いる import re def clean_strings(strings): result = [] for value in strings: value = value.strip() # 両端(先頭、末尾)の文字を削除:引数を指定しない場合、先頭/末尾の空白を削除する value = re.sub('[!#?]','',value) # !#?を''(何もない)に置換 value = value.title() # 単語の先頭を大文字にする result.append(value) return result clean_strings(states) # 2. 文字列に適用したい操作のリストを作る states = [' Alabama ', 'Georgia!', 'Georgia', 'georgia', 'FlOrIda', 'south carolina##', 'West virginia?'] def remove_punctuation(value): return re.sub('[!#?]','',value) clean_ops = [str.strip, remove_punctuation, str.title] # 適用したい全操作のリスト def clean_strings(strings, ops): result = [] for value in strings: for function in ops: value = function(value) result.append(value) return result clean_strings(states, clean_ops) # map関数でリストなどの何らかのシークエンスの各要素に関数を適用できる for x in map(remove_punctuation, states): print(x)
2.2.4 無名関数(ラムダ関数)
は、値を戻すような処理を一文で定義して書く関数、すなわち無名関数(ラムダ関数)をサポートする。
# 無名関数はlambdaキーワードで定義する def short_function(x): return x*2 equiv_anon = lambda x: x * 2 # ラムダ関数を用いると、タイピング量が減り、コードが明確になる def apply_to_list(some_list, f): return [f(x) for x in some_list] ints = [4, 0, 1, 5, 6] apply_to_list(ints, lambda x: x * 2) # このようにラムダ関数を直接書くと、別行で関数を定義するよりも分かりやすい # 別の例 strings = ['foo', 'card', 'bar', 'aaaa', 'abab'] strings.sort(key = lambda x: len(set(list(x)))) print(strings)
2.2.5 カリー化
既存の複数の引数を持つ関数から、その引数の一部だけを引数に持つ関数を新たに定義できる。このように引数の部分適用をすることをカリー化という。
# カリー化の例 def add_numbers(x,y): return x + y add_five = lambda y: add_numbers(5,y) add_five(5)