とらりもんHOME  Index  Search  Changes  Login

python入門: 関数

前節で, 以下のような数列の和を使ってπの近似値を求めた:

np.sqrt((6/(np.arange(1,1001)**2)).sum())

これはn=1000までの計算だが, n=10000やn=100000の場合を求めるのに, いちいち式の中をいじってやり直すのは面倒だった。そういうときに便利なのが「関数」という考え方である。pythonのようなプログラミング言語での「関数」は数学の「関数」とは違って, ひとかたまりの処理をまとめた, プログラムの「部品」のようなものなのだが, ともあれ, 以下を打ってみよう(ipython3で):

import numpy as np
def pi_kinji(n):
  return(np.sqrt((6/(np.arange(1,n+1)**2)).sum()))

そして, 以下のように打ってみよう:

pi_kinji(10)
pi_kinji(100)
pi_kinji(1000)
pi_kinji(10000)

どうだろうか? n=10からn=10000まで, 様々なnの値について, 一瞬でπの近似値を出せた。このpi_kinji()というのが, 関数である。この関数の()内に好きなnの値を入れると, 例の数列の和を計算して6倍してルートをとった値を返すのである。では, 打ったものの意味を見てみよう。

 まずdefとはdefineの略であり, 「今から関数を定義します」という宣言である。それに続くpi_kinjiはここで新たに作る関数の名前(πの近似という意味で, 私がテキトーにつけた)。その後に()を続けて, ()の中には引数を表す変数名(ここではn)を定義する。

 その次の行に, インデントして計算式を書き, それをreturn()というのでくるんでいる。このreturn()は, 求めた結果を関数の結果として返す, という意味である。インデントが必要なのは, defで宣言した関数の定義を, どこまでの行が表しているかを明示するためである。

 ところが, こうやって定義した関数も, pythonシェルを抜けると消えてしまう。やってみよう。

課題: いったんpythonシェルを抜け, 再度入って,

pi_kinji(100)

と打ってみよ。エラーが出るだろうか? それを確認したら, pythonシェルから抜けること。

 そこで, このような関数を, pythonスクリプトにするのである。やってみよう。Linuxシェルで, 以下のようなテキストファイルをkisosu.pyというファイル名で作れ:

import numpy as np
def pi_kinji(n):
  return(np.sqrt((6/(np.arange(1,n+1)**2)).sum()))

def pi_kinji2(n):
  return(((90/(np.arange(1,n+1)**4)).sum())**(1/4))

これを保存し, kisosu.pyのあるディレクトリからpythonシェル(ipython3)を立ち上げよ。そして, 以下のように打ってみよう:

import kisosu as ks
ks.pi_kinji(100)
ks.pi_kinji(1000)

どうだろう? pi_kinji関数が, 使えるではないか! ここでもう気づいただろうか,

import kisosu as ks

というのがポイントである。この呪文によって, kisosu.pyというpythonスクリプトが読み込まれ, そこで定義されている関数が利用可能になる。ただし, そのためには, ks.というのを関数名の最初につけねばならない。これはちょうど,

import numpy as np

と打つとnumpy関係のいろんなものが使えるが, そのためにはnp.を最初につけねばならないのと同じである。

 さて, kisosu.pyには, pi_kinjiだけでなく, pi_kinji2という関数もついでに作った。それを試してみよう。すでにkisosu.pyのインポートは終わっているので, いきなり以下のように打ってよい。

課題: 以下のように打ってみよ:

ks.pi_kinji2(100)
ks.pi_kinji2(1000)

どうだろう? ks.pi_kinji(100)やks.pi_kinji(1000)よりもずっと良い精度でπを推定できているだろう。pi_kinji2関数で使ったのは, 以下のような数列の和である:

1/(1^4)+1/(2^4)+1/(3^4)+...+1/(n^4)

これは(π^4)/90に収束することは, 諸君は既に学んでいる。そしてその収束は,

1/(1^2)+1/(2^2)+1/(3^2)+...+1/(n^2)

が(π^2)/6に収束するよりもずっと速いのである。

ともあれ, これで, pythonにおける「関数」の概要と, それをどう作ったり使ったりするかがわかっただろう。

Last modified:2019/01/30 19:22:17
Keyword(s):
References:[python入門]