06_関数の応用
- 関数にデフォルトの引数を定義する
- 引数のキーワード指定
- 引数はカンマで区切って、複数指定できる
- 順番には大事な意味がある。
- データの種類(データの型)
- あえて順番を入れ替えて呼び出す方法がある。
- 関数に引数を渡す時、引数の名前を明示する。
- 1つだけデフォルト値以外の引数を指定したいときに、キーワード指定を使うことがある。
- 関数とローカル変数
- 関数の中と外で同盟の変数を定義すると、別の変数として扱われる
- 関数内からは外の変数が見えるが、外から中は見えない
- 関数内世界のような機能を、「名前空間」や「ネームスペース」と呼ぶことがある
# coding: utf-8 # In[4]: # 関数にデフォルト引数を定義する def fizzbuzz(count=100, fizzmod=3, buzzmod=5): for cnt in range(1, count+1): if cnt%fizzmod == 0 and cnt%buzzmod == 0: print("FizzBuzz") elif cnt%fizzmod == 0: print("Fizz") elif cnt%buzzmod == 0: print("Buzz") else : print(cnt) fizzbuzz() # In[5]: # 引数のキーワード指定 ## class int(x, base=10) ## https://docs.python.jp/3/library/functions.html#int int(base=2, x="1010") # In[6]: # 関数の外側で定義した変数を関数内で使う local_var = 1 def test_func(an_arg): local_var = an_arg print("test_func()の中", local_var) test_func(200) print("test_func()の外", local_var) # In[ ]:
05_ループの応用
- whileでループを作る
- ループにシーケンスを添えないこと。
- 繰り返し変数もない
- 条件式を添える
- continue文を使う
- それ以降のループブロックを実行せず、ブロックの最初まで戻ることができる。
- 特定の条件にあるとき、ブロックの一部を実行せず、ループを続けたいときに使うと便利です。
- ループのelse
- for文にelseを添えると、ループの実行が終わった後に実行されるブロックを定義できる。
- for文のブロックでbreak文が実行されたときは、else以降のブロックは実行されない。
while文の記法
while 条件式: ループ内で実行するブロック
# coding: utf-8 # In[3]: ### FizzBuzz問題を解くプログラム cnt = 1 while cnt <= 100: if cnt % 3 == 0 and cnt % 5 == 0: print("FizzBuzz") elif cnt % 3 == 0: print("Fizz") elif cnt % 5 == 0: print("Buzz") else: print(cnt) cnt = cnt + 1 # In[14]: ### じゃんけんプログラム from random import randint # ディクショナリの定義をする hands = {0:"グー", 1:"チョキ", 2:"パー",} # タプル をキーに使いディクショナリに設定する # 勝ち負けのルール rules= {(0,0):"あいこ" , (0,1):"勝ち" , (0,2):"負け", (1,0):"負け" , (1,1):"あいこ" , (1,2):"勝ち", (2,0):"勝ち" , (2,1):"負け" , (2,2):"あいこ"} while True: pc_hand = randint(0,2) user_hand_str = input("0:グー, 1:チョキ, 2:パー, 3:やめる") # じゃんけんをやめる if user_hand_str == "3": break # 不正な入力の場合、ループの先頭に戻る if user_hand_str not in ("0", "1", "2"): continue # ユーザーの手を数値に変換 user_hand = int(user_hand_str) print("あなた" + hands[user_hand]+ "、コンピュータ:" + hands[pc_hand]) print(rules[user_hand, pc_hand]) # In[23]: ### for文とelse文の組み合わせ (素数です) a_num = 59 for num in range(2, a_num): print(a_num, num) if a_num % num == 0: print(a_num, "は素数ではありません") break else: print(a_num, "は素数です") # In[22]: ### for文とelse文の組み合わせ(素数ではありません。) a_num = 60 for num in range(2, a_num): print(a_num, num) if a_num % num == 0: print(a_num, "は素数ではありません") break else: print(a_num, "は素数です") # In[ ]:
04_if文の応用
- 比較演算子
- ==
- !=
- >
- <
- >=
- \<=
- in
- 条件式は、True,Falseという2種類の値を返す。真偽値
- 違うデータ型の比較を行うことはできない。
- “100” > 200 のような比較を書いて、自動的に文字列を数値に変換してくれない。
- int(“100”) > 200 のように、明示的に変換する必要がある
- 論理演算
- and
- or
- not
# coding: utf-8 # In[1]: 1+1 == 2 # In[6]: # 5の0乗 + 9 = 10 5**(4-4)+9 == 10 # In[7]: 5 > 2 # In[8]: 100 == 100.0 # In[9]: "かなこ" != "かなこぉ↑↑" # In[10]: [1, 2, 3] == [1, 2, 3] # In[14]: ### 条件式に論理演算子を使った例 v = 30000 if v < 28400: print("地上に落下します") if v > 28400 and v < 40300: # print("月とお友達です") if v > 40300 and v < 60100: print("惑星の仲間入りです") if v == 60100: print("アルファケンタウリを目指せ") # In[15]: # In[ ]:
03_タプルを使う
- タプルは、リストにとてもよく似た性質をもっている。
- タプルは、要素を変更できないシーケンス
- 複数の要素をもつことができる
- インデックスを使って要素にアクセスできる。
- 要素の変更ができない。
- タプルの定義方法
- (要素, 要素, …)
- タプルから要素を取り出す
- タプル名[インデックス]
- タプルは要素を変更することができない
- TypeError: ‘tuple’ object does not support item assignment が発生する
- タプルは、要素を削除することができない。(変更されることになる)
- タプル同士を連結することができる
- +演算子を使う
- タプルもリストと同じように、len(),in演算子,スライスを使える。
- 要素が1つだけのタプルを定義するには、少しコツが必要。
- 「(10,)」のように、要素の後にカンマを補う必要がある。
- タプルの利点
- ディクショナリのキーや、setの要素にすることができる。
補足
- 2点間の距離の求め方
- 緯度と経度の差を二乗して足す
# coding: utf-8 # In[1]: ### タプルの定義 month_names = ('January', 'February', 'March', 'April', 'May', 'June', 'July') month_names # In[2]: ### タプルから要素を取り出す month_names[1] # In[3]: ### タプルの要素を変更する month_names[0] = '睦月' # In[4]: ### タプル同士の連結 ### month_names2 = month_names + ('August', 'September', 'October', 'November', 'December') month_names2[11] # In[5]: ### タプルをキーとしたディクショなりの作成 pref_capitals = {(43.06417, 141.34694):"北海道(札幌)", (40.82444, 140.74): "青森県(青森市)", (39.70361, 141.1525):"岩手県(盛岡市)"} pref_capitals # In[11]: ### 指定した緯度、経度に合致する県庁所在地を調べる loc = (39.70361, 141.1525) for key in pref_capitals: if loc == key: print(pref_capitals[key]) break # In[19]: ### 指定した緯度、経度に最も近い県庁所在地を調べる # 調べたい地点の緯度、経度 loc = (41.768793, 140.72881) # 最寄りの県庁所在地を保存する変数 nearest_cap = '' # 最寄りの地点までの距離を保存する変数 nearest_dist = 10000 # keyでループする for key in pref_capitals: dist = (loc[0]-key[0])**2+(loc[1]-key[1])**2 print(key, pref_capitals[key]) if nearest_dist > dist: # より近い地点が見つかったので、入れ替える。 nearest_dist = dist nearest_cap = pref_capitals[key] print(nearest_cap) # In[22]: aaa = (555,333,333) aaa # In[ ]:
02_set(集合)を使う
- setは、集合を扱うために、Pythonに追加されました。
- 複数の要素を持つデータの種類のこと
- リストと同じように複数の要素を保存することができる。
- リストと違い、中の要素が重複しないように管理される。
- 存在する値を登録しようとしても、新しい要素が追加されない。
- インデックスを使って、要素を取り出すことができない。
- 和集合
- 複数のsetを足したsetを作る
- |演算子を使う
- 差集合
- あるsetに含まれる要素を他のsetから取り除く
- -演算子を使う
- 交わり
- 共通する要素だけを抜き出す
- &演算子を使う
- 対象差 ( XOR のような操作)
- あるsetと他のsetを合わせて、2つのsetが共通して持つ要素だけを取り除く
- ^演算子を使う
- 集合演算
- 和集合、差集合、交わり、対象差を集合演算と呼ぶ。
- setを定義する
- {要素, 要素, 要素}
- リストやディクショナリを要素として追加することはできない。
- 変更できると重複した要素を持たないという性質を保てないため。
- TypeError: unhashable type:“list"のようなエラーが発生する
- setの集合演算では、ビット演算や、論理演算で使う演算子が利用されている。
- setはfor文にシーケンスとして添えることができる。
- リストからsetを作ることができる
- 組み込み関数set()を使う。
- リストと同じように、len(),max(),min(), sum()を使える
- リストと同じように、in演算子を使って、要素の検索をすることができる。
- if文の中で、<=を使うと、あるsetが他の部分集合かどうかを調べることができる。
集合の参考イメージ
http://suugaku-bukai.esnet.ed.jp/2008/study/2004/20040202.htm
# coding: utf-8 # In[3]: # setの定義 dice = { 1,2, 3, 4, 5, 6 } coin = {"表", "裏"} print(dice) print(coin) # In[4]: ### 和集合を得る ### # 素数のsetを定義する prime = {2, 3, 5, 7, 13, 17} # フィボナッチ数のsetを定義する fib = {1, 1, 2, 3, 5, 8, 13} prime_fib = prime | fib prime_fib # In[5]: ### 差集合を得る ### # サイコロの目のsetを定義 dice = { 1, 2, 3, 4, 5, 6} # 偶数のsetを定義する even = { 2, 4, 6, 8, 10} odd_dice = dice - even odd_dice # In[6]: ### setの交わりを得る ### prefs = {"北海道", "青森", "秋田", "岩手"} capitals = {"札幌" , "青森", "秋田", "盛岡"} pref_cap = prefs & capitals pref_cap # In[8]: ### setの交わりを得る ### prefs = {"北海道", "青森", "秋田", "岩手"} capitals = {"札幌" , "青森", "秋田", "盛岡"} pref_cap2 = prefs ^ capitals pref_cap2 # In[10]: ### リストをsetに変換する ### # リストを定義する codon = ['ATG', 'GCC', 'TCC', 'AAG', 'TTC', 'TGG', 'GAC', 'TCC'] # リストをsetに変換する s_codon = set(codon) print(len(codon), len(s_codon)) print(s_codon) # In[12]: ### 要素の検索とsetの比較 ### prime = {2, 3, 5, 7, 13, 17} fib = {1, 1, 2, 3, 5, 8, 13} prime_fib = prime & fib print(prime_fib) if 13 in prime_fib: print("13は素数で、フィボナッチ数でもある") if {2, 3} <= prime_fib: print("2,3は素数で、フィボナッチ数でもある") # In[ ]:
01_ディクショナリ(辞書)を使う
- 要素にキーをつけて、複数のデータを管理する
- {キー1:値1, キー2:値2 … }
- キーには、文字列や数値が使える。
- リストをキーとして登録することはできない。
- キーに対応する値は、文字列や、数値、リスト、他のデータ型も使える。
- キーを使って要素を取り出す。
- ディクショナリの要素を取り出すには、キーを使う。
- ディクショナリ名[要素のキー]
- 存在しないキーを指定した場合、KeyError になる.
- ディクショナリの要素を取り出すには、キーを使う。
- ディクショナリは、キーで要素を管理するデータ型
- 順番という概念がない。
- ディクショナリを表示するときには、文字コード順に並びます
- キーが英数字ならアルファベット順に表示される。
- キーを使って要素を入れ替える
- purple[‘キャッチフレーズ’] = “鋼少女”
- 新しいキーと値を追加する
- ディクショナリの場合、要素を足すというよりは挿入するイメージ
- キーを使って要素を削除する。
- ディクショナリから要素を削除するには、del文を使う。リストの要素を削除するのと似ている。
- キーの存在確認
- in演算子を使う。
- キーを使ったループ
# coding: utf-8 # In[4]: # ディクショナリを使う # ディクショナリの定義 purple = { "ニックネーム" : "れにちゃん", "出身地" : "神奈川県", "キャッチフレーズ" : "感電少女" } # In[3]: # ディクショナリから値を取り出す print(purple['出身地']) # In[5]: # ディクショナリ「purple」の内容を確認する purple # In[6]: # キーを使って要素を入れ替える purple['キャッチフレーズ'] = "鋼少女" purple # In[7]: # 要素の追加 purple["生年月日"] = "1993年6月21日" purple # In[8]: # 要素の削除 del purple['ニックネーム'] purple # In[9]: # 存在しないキーを指定した場合 purple["ニックネーム"] # In[16]: # in演算子を使った関数の定義 def convert_number(num): # アラビア数字とローマ数字の対応表をディクショナリに定義 roman_nums = {1:"I", 2:"II", 3:"III", 4:"IV", 5:"V", 6:"VI", 7:"VII", 8:"VIII", 9:"IX"} # ディクショナリのキーとして引数の整数が存在していたら # キーに対応する値を戻り値にする if num in roman_nums: return roman_nums[num] else : return "[変換できません]" for number in range(1,11) : print( convert_number(number) ) # In[17]: purple = {"ニックネーム" : "れにちゃん", "出身地" : "神奈川県", "キャッチフレーズ" : "感電少女", "生年月日" : "1993年6月21日" } for key in purple: print(key, purple[key]) # In[ ]:
08_モジュールを使う
- プログラムでよく使うデータ、関数などは、Pythonに内蔵されていていつでも使えるようになっています。
- ここでいう組み込みとは、「Built in」
- Pythonに付属しているモジュールの集合体のことを標準ライブラリと呼んでいる。
- turtle → 標準ライブラリ
- matplotlib → Anacondaのライブラリ
- モジュールをインポートする
- import モジュール名
- as を使うと、別名で使うことができる。
- import モジュール名 as 読み込む名前
- from を使ったインポート
- from というキーワオド組み合わせるとモジュールにある関数などを直接インポートできる。
- モジュールの関数を直接インポートすると、実行時にモジュール名を書く必要がなくなる
- アスタリスク(*)を使うと、モジュールの持っている関数などをまとめてインポートできる。(副作用が大きいのがデメリット)
- モジュールの探し方
# coding: utf-8 # In[5]: # モジュールを使う import random # 0 < x < 1 の乱数を得る print(random.random()) # 0 < x <= 6 の乱数を得る print(random.randint(0, 6)) a_list = [0, 1, 2, 3, 4, 5] # リストをランダムに入れ替える random.shuffle(a_list) print(a_list) # リストの要素を1つランダムに選ぶ print(random.choice(a_list)) # In[6]: # fromを使ったimport文の気泡 from statistics import median monk_fish_team = [158, 157, 163, 157, 145] volleyball_team = [143, 167, 170, 165] print( median(monk_fish_team) ) print( median(volleyball_team) ) # In[ ]: