Python Essentials

本文の内容

データ型

bool型(真偽型)…Trueは0や1との加減乗除も可能
整数型、小数型…Python2.x系では整数同士の割り算では常に整数型しか返さない
       → from __future__import division とすることで可能になる
複素数型
リスト型、辞書型、タプル、セット…データをまとめて管理することができる

ファイルの読み書き

・テキストエディタを使わずにPythonのコードを使ってシェル上でテキストファイルの作成が可能
・ディレクトリが違いファイルを開けなかった時…open('目的のファイルの上層ファイル/ファイル名','r')で読み込める
・str.format(*args,**kwargs)…文字列フォーマット。文字列の内部に埋め込みたいオブジェクトを指定できる。
・zip関数…タプルのリストを返す。前回参照。

関数

・importせずに使える関数…max,range,str,type,all,anyなど
・lambda…一行で関数を定義できる
・キーワード引数と位置引数…名前(キーワード)が指定されているか否か。
  (注意)plot(x,'b-',label="white noise")は、
      plot(x,label="white noise",'b')とすると動かないが、
          plot(x,label="white noise",color='b')ならば動く。

Exercise

Exercise1

Part1

x_valsとy_valsという数字のリストに対し、その内積を計算するプログラムを書け、という問題。

zip()で順番がついたタプルのリストを作成することができる。
例えばx_vals=[1, 2]、y_vals=[3, 4]とすると、zip(x_vals, y_vals)=[(1, 3)(2, 4)]となる。
このリストの要素(x, y)についてその積をとって足し合わせると内積が計算できる。

sum(x * y for x, y in zip(x_vals, y_vals))

Part2

([x % 2 == 0 for x in range(100)])というリストの中身は[True, False, True, False, …]となっている。
これを足すと、Trueは1、Falseは0としてカウントされるので、結局偶数の数が数えられる。

なお、([x for x in range(100) if x % 2 == 0]) というリストにすると、その中身は[0, 2, 4, 8, …]となっているので、これを足すと0から99までの偶数の総和をカウントできる。

Part3

pairs = ((2, 5), (4, 2), (9, 8), (12, 10))として、その中で数字の組が両方偶数であるものの数をカウントするプログラムを書け、という問題。

([x % 2 == 0 and y % 2 == 0 for x, y in pairs])
とすると、その中身は[False, True, False, Tru]となるので、Part1と同様、その和をとれば偶数のペアの数が数えられる。

なお、「pairsの中で数字が両方偶数であるペアを抜き出す」というプログラムは、
[(x,y) for x,y in pairs if x % 2 == 0 and y % 2 == 0]
とすればよい。pairsの要素はタプルなので、最初のx, yを()で囲むのが重要!

Exercise2

enumarate()を使うことで、zip()を使わなくても順番が付けられる。
この場合」、(i,a in enumerate(coeff))とすることで、i=0,1,2…に対してcoeffの中の数字がそれに対応して出て来る。

Exercise3

文字型を引数とし、その中で大文字の数を数える関数を作れ、という問題。

解答は、まずcount = 0と定義し、引数の中の各文字に対して、それが大文字でかつアルファベットであればcountに1を足していき、最後にcountを返す、という関数になっている。これで結局は文字列の中の大文字の数を数えられるようになっている。

ちなみに、「アルファベットである(isalpha)」という指定がないと、スペースやピリオドであってもcountに加えてしまうので注意が必要である。

Exercise4

ふたつのsequence(リストとかタプル)aとbを引数とし、aの要素が全てbにも含まれていれば(つまりaがbの部分集合であれば)Trueを、そうでなければFalseを返す関数を書け、という問題。

解答では、まずis_subset(部分集合である)=True として、seq_aの要素1個1個に対し、もしそれがseq_bに入っていなければis_subset=Falseに変更し、最後にis_subsetを返す関数となっている。seq_aの要素が全てseq_bにも入っていればis_subset=Trueのまま変更されることは無くTrueが返され、そうでなければFalseが返されるので、結局設問の要求を満たしていることになる。

なお、セット型(set)データのメソッドを使えばもっと簡単に出来る。ふたつのセットaとbに対してaがbの部分集合であるかどうかを判定するためには、issubsetメソッドを使えばよく、a.issubset(b)とすれば、aがbの部分集合であればTrueを、そうでなければFalseを返す。sequanceに対してset(sequance)とするとセット型のデータに変換することができ、別解ではこの方法をとっている。

Exercise5

関数fおよびa≦x≦bをみたすxについて、線形近似を用いてf(x)の値の概算を行う問題。
aからbまで均等に配置されたn個の点をポイントとよぶことにする。
同様に、あるポイントから隣り合うポイントへの移動をステップとよぶことにする。
1ステップの長さは(b-a)/(n-1)となる。
最初はポイントaにいる。
もし今のポイントがxより小さかったら1ステップ進む。これを何回か繰り返してゆく。
すると、何ステップか進んだところでxを通り過ぎるはずである。
その直前にいたポイント(Solutionではuとおかれている)と現在のポイント(同じくvとおかれている)を用いて、2次元平面上(p-q平面上とする)に(u,f(u))(v,f(v))の2点をとり、直線で結ぶ。
この直線上にあり、p=xをみたす点のq座標が求めるべきf(x)の近似値である。
このq座標はf(u)+(x - u)*(f(v)-f(u))/(v - u)と表される。
nを大きくしていくと近似の精度は上がっていく。
ちなみに、n→∞ではv-u→+0なので、(f(v)-f(u))/(v - u)=f'(x)となる。

授業ではlinspaceを用いて関数fを折れ線で表現した。
Solutionのコードでは、関数linapprox(f,a,b,n,x)はxに1つの値(int型もしくはfloat型)が入ることを想定しているためlinspaceで作られた複数の値を含むarray型の引数をxとおくとエラーが出た。
正しく描画するためにはfor文を用いて、arrayの中の値を1個1個取り出し繰り返し処理する必要がある。

  • 最終更新:2015-04-27 18:28:52

このWIKIを編集するにはパスワード入力が必要です

認証パスワード