2008-06-30
Pythonのお勉強私的メモ(その3・基本以前・ユニコードと日本語処理/復習1 環境・文字列・リスト・フロー制御・リスト詳細・del文・ループのテクニック)
Pythonのお勉強シリーズ | |
第3回。今日も曇ってて温度低めで過ごしやすい。引き続きお勉強。
これは超初心者の勉強メモだからなんの参考にもなりません!読んでもPythonのお勉強ができる訳ではありません!ぐぐるから間違えてきちゃった人は戻った方がいいよ!
ユニコードと日本語処理
コデックス
- Pythonには2種類の文字列型がある。1つは文字列型、もう1つはユニコード型。日本語を扱うにはユニコード型がよい。
- コデックス(codecs)という仕組みがあり、ユニコード文字列からEUC-JPやShiftJISなどの8ビット文字列に変換できる。
ユニコード型と日本語の境界
マルチバイト文字列の区切りを容易に扱える。便利
>>> u=u"あいうabc" >>> print u[2] う
インデックス2の文字を読み出すと、ちゃんと3番目が返ってくる。
>>> ru="あいうabc" >>> print ru[2]
インデックス2の文字を読み出すので、「あ」の3バイト目(元文字はUnicodeだから1文字あたり3バイト使ってる)が返ってくる。
他のエンコードからユニコード文字列への変換
u=unicode('あいう','euc-jp','replace')
第1引数は変換対象文字、第2引数はエンコードタイプ、第3引数は変換中に起こったエラーに対する対応(ここでは特定文字に置き換え)
ユニコード文字列から他のエンコードへの変換
u=u"あいう"
u.decode('iso-2022-jp','ignore')
decode()関数を使う
第1引数はエンコードタイプ 第2引数は変換中に起こったエラーに対する対応(ここでは変換に失敗した文字をそのまま残す)
プログラム内部での日本語の扱い
おわちゃった
この本(みんなのPython Webアプリ編)だと言語としてのPythonの説明はここまでだ。あとはwebアプリ作成編になっている。うーむ。間違って買った本とはいえ、ある程度Pythonの説明があったのは感謝するべきか。
しかしこれだけでPythonのお勉強をおわりにする訳にもいかない。まださわり程度しか理解できていないのだ。続きはPython チュートリアル*1を流し読みして気になった所だけ雑多にまとめることにする。
復習 環境
起動時の引数
起動時のコマンドライン引数は「sys.argv」というリスト変数に入ってる。(import sysしてから使う)
実行可能な Python スクリプト
#! /usr/bin/env python
とヘッダに書いて実行権限を付加する。
ソースコードのエンコード指定
# -*- coding: encoding -*-
とヘッダに書く
復習 文字列
文字列リテラルを複数行にまたがって記述する場合、継続行にしたければ、末尾にバックスラッシュをつける
hello = r"This is a rather long string containing \ several lines of text much as you would do in C." print hello
以下のようになる
This is a rather long string containing several lines of text much as you would do in C.
「"""」の三重クォートを使うと、改行符号いれなくても改行される
print """ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to """
以下のようになる
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
互いに隣あった二つの文字列リテラルは自動的に連結される
>>> 'str' 'ing' 'string'
スライスで最初のインデックスを省略すると、0と見なされる。2番目を省略すると、全文字
>>> word[:2] # 最初の 2 文字 'He' >>> word[2:] # 最初の 2 文字を除くすべて 'lpA'
Pythonの文字列は変更できない!
>>> word[0] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesn't support item assignment
なので、新たな文字列の生成で対応する
>>> 'x' + word[1:] 'xelpA' >>> 'Splat' + word[4] 'SplatA'
インデックスを負の数にして、右から数えることもできる
>>> word[-1] # 末尾の文字 'A' >>> word[-2] # 末尾から 2 つめの文字 'p' >>> word[-2:] # 末尾の 2 文字 'pA' >>> word[:-2] # 末尾の 2 文字を除くすべて 'Hel'
文字列の長さは組込み関数len()で取得できる
>>> s = 'supercalifragilisticexpialidocious' >>> len(s) 34
Unicode文字を文字コードで表すには、文字列の頭に「ur」を付ける(Unicode Raw文字列)。バックスラッシュで文字コードを入力できる。
>>> ur'Hello\u0020World !' u'Hello World !'
復習 リスト
スライスで項目置換できる。
>>> # いくつかの項目を置換する: ... a[0:2] = [1, 12] >>> a [1, 12, 123, 1234]
スライスで項目除去できる
>>> # いくつかの項目を除去する: ... a[0:2] = [] >>> a [123, 1234]
スライスで項目追加できる
>>> # いくつかの項目を挿入する: ... a[1:1] = ['bletch', 'xyzzy'] >>> a [123, 'bletch', 'xyzzy', 1234]
スライスでリストを追加
>>> a[:0] = a # それ自身 (のコピー) を先頭に挿入する >>> a [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
入れ子のリスト(ほかのリストを含むリスト)
>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
復習 フロー制御
break 文と continue 文と ループの else 節
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, 'equals', x, '*', n/x ... break ... else: ... # 因数が見つからずにループが終了 ... print n, 'is a prime number' ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3
pass文
何もしない文。なんか親近感わいた
while True: pass # キーボード割り込み (keyboard interrupt) をbusy-wait で待つ
ラムダ形式
キーワード lambda を使うと、名前のない小さな関数を生成できる。Lispから来た機能
>>> def make_incrementor(n): ... return lambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 43
復習 リスト詳細
リストのメソッド
| append(x) | リストの末尾に要素を一つ追加します。 a[len(a):] = [x] と等価です。 |
| extend(L) | 指定したリスト中のすべての要素を対象のリストに追加し、リストを拡張します。 a[len(a):] = L と等価です。 |
| insert(i, x) | 指定した位置に要素を挿入します。第 1 引数は、リストのインデクスで、そのインデクスを持つ要素の直前に挿入が行われます。従って、a.insert(0, x) はリストの先頭に挿入を行います。また a.insert(len(a), x) は a.append(x) と等価です。 |
| remove(x) | リスト中で、値 x を持つ最初の要素を削除します。該当する項目がなければエラーとなります。 |
| pop([i]) | リスト中の指定された位置にある要素をリストから削除して、その要素を返します。インデクスが指定されなければ、a.pop() はリストの末尾の要素を返します。この場合も要素は削除されます。 (メソッドの用法 (signature) で i の両側にある角括弧は、この引数がオプションであることを表しているだけなので、角括弧を入力する必要はありません。この表記法は Python Library Reference の中で頻繁に見ることになるでしょう。) |
| index(x) | リスト中で、値 x を持つ最初の要素のインデクスを返します。該当する項目がなければエラーとなります。 |
| count(x) | リストでの x の出現回数を返します。 |
| sort() | リストの項目を、インプレース演算 (in place、元のデータを演算結果で置き換えるやりかた) でソートします。 |
| reverse() | リストの要素を、インプレース演算で逆順にします。 |
リストをスタックとして使う
スタック(後入れ先出し)として使う場合、追加はappend、取り出しはpopを使う
>>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4]
リストをキューとして使う
リストをキュー(先入れ先出し)として使う場合、追加はappend、取り出しはpop(0)を使う(マルチスレッド向けに排他を実装したQueueモジュールは別途あるらしい)
>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry が到着 (arrive) する
>>> queue.append("Graham") # Graham が到着する
>>> queue.pop(0)
'Eric'
>>> queue.pop(0)
'John'
>>> queue
['Michael', 'Terry', 'Graham']
実用的なプログラミングツール
STLのアルゴリズムみたいなものかな?リストに対する便利な操作。とりあえずfilter() 、 map() 、reduce()
- filter(function, sequence)は、シーケンスの要素の中からfunctionの結果がTrueになる要素を返す
>>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23]
- map(function, sequence)は、シーケンスの要素をfunctionに渡して、その結果を積んだリストを返す
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] >>> seq = range(8) >>> def add(x, y): return x+y ... >>> map(add, seq, seq) [0, 2, 4, 6, 8, 10, 12, 14]
- educe(func, sequence)は、シーケンスの最初2つの要素をfunctionに渡す、次にその結果と次のシーケンスの要素とをfunctionに渡してをシーケンスの最後まで繰り返し、その結果を返す
>>> def add(x,y): return x+y ... >>> reduce(add, range(1, 11)) 55
内包表記
なのでPythonの技法:リストの内包表記*2の記事より補足。元はHaskellなのかぁ
通常のPythonリスト
>>> wordlist = ['HELLO', 'World', 'how', 'aRe', 'YOU?']
上記のwordlistを小文字にしたい場合、ダサイ方法だと
>>> l = []
>>> for word in wordlist:
l.append(word.lower())
>>> l
['hello', 'world.', 'how', 'are', 'you?']
と書く、これをmapを使って書き直すと
>>> import string >>> map(string.lower,wordlist) ['hello', 'world.', 'how', 'are', 'you?']
となる。これをリストの内包表記を使って書くと
>>> [word.lower() for word in wordlist] ['hello', 'world.', 'how', 'are', 'you?']
と書ける。内包表記は「式、続いて for 節、そしてその後ろに続くゼロ個かそれ以上の for 節または if 節からなります。式をタプルで評価したいなら、丸括弧で囲わなければなりません」だそうだ。
やっと理解できた。filterにも使えて、すべて小文字の要素のみ取り出す場合、
>>> [word for word in wordlist if word.islower()] ['how']
となる。mapとfilter両方使って、すべて小文字の要素以外を取り出して、結果を小文字に変換(ややこしい)すると
>>> [word.lower() for word in wordlist if not word.islower()] ['hello', 'world.', 'are', 'you?']
となる。
復習 del文
インデックスで要素が消せる
>>> a [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.25, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.25, 1234.5]
del は変数全体の削除にも使える。
>>> del a
復習 ループのテクニック
辞書
iteritems()メソッドを使うと、キーとそれに対応する値を同時に取り出せる
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
シーケンス
numerate() 関数を使うと、インデックスと要素を同時に取り出す
>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe
zip()関数を使うと、複数のシーケンスから同時に要素を取り出す
>>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print 'What is your %s? It is %s.' % (q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue.
reversed関数で、シーケンスを逆にループ
>>> for i in reversed(xrange(1,10,2)): ... print i ... 9 7 5 3 1
sorted関数で、シーケンスを並び順にループ
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): ... print f ... apple banana orange pear
おなかすいた
今日はここまで。あーつかれた
鮭を焼いて食うかなぁ。納豆もいいなぁ
2008-06-28
Pythonのお勉強私的メモ(その2・基本以前・フロー制御/関数/モジュール/オブジェクト指向)
Pythonのお勉強シリーズ | |
第2回。引き続きお勉強中
これは超初心者の勉強メモだからなんの参考にもなりません!読んでもPythonのお勉強ができる訳ではありません!ぐぐるから間違えてきちゃった人は戻った方がいいよ!
フロー制御
ブロックの表現
Pythonはブロックを表現するのにインデント(字下げ)を利用する。括弧{}とか使わない
| プログラム | |
| if条件 | |
| インデント | ブロック※ |
| プログラム |
※ここのブロック(if条件で実行されるかたまり)を表現するのにインデントを使う
条件分岐
if year>2000 and year<=2100: print "21st century" elif year>2100 and year<=2200: print "22nd century" else: print "20th century(maybe)"
シーケンスを使った繰り返し(for文)
for cnt in range(10): # 0から9までの数を表示する print cnt
- pythonのfor文では、リストのようなシーケンスをinの後に書く。
- シーケンスの内容を1つずつ取り出し、inの前にある繰り返し変数に代入しながら、for分の内部を処理していく。へー
- Pythonではブロックごとに名前空間が区切られない(名前空間って概念があるらしくて、それが変数スコープを決めている?)そのため、for分で定義した繰り返し変数や、ループブロック内で定義した変数はfor文の後でも利用可
条件を使った繰り返し(while文)
while cnt < 10: print cnt cnt+=1
関数定義と呼び出し
関数定義
def a_function(arg1, arg2): """2つの数値をかけ算して返す""" return arg1*arg2
- def文のすぐ下にある文字列はドキュメンテーション文字列で、関数の説明を書いておくためのもの(Pythonの決まり事)
- 関数は呼び出し可能オブジェクトである。関数を定義すると、関数として呼び出される変数のような物(=オブジェクト)が作られる
- 別の変数に関数を代入することもできる
引数の定義
- デフォルト値指定には「arg=10」と書く
def a_function(arg=10):
def a_function(*param):
- 「**args」用ようにアスタリスクを2つ付けた引数を使った場合、関数は不特定のキーワード引数を受け取れるようになる。argsには辞書が渡される。関数内では、キーワード引数の引数名をキーに、値が登録された状態で利用できる
def a_function(**args):
関数の戻り値とアンパック代入
- リターン文はreturn
- 複数のデータを一度に戻り値として返却できる(アンパック代入と呼ぶ)
return a,b,c #--- a,b,c=somefunc()
関数と名前空間
- Pythonでは代入を行う事で変数を定義する。
- 変数は、どこで定義されたかで利用範囲が制限される。
- Pythonの関数内では、特別な名前空間がつくられる。関数内で定義された変数は、この名前空間内だけで利用できる。
関数の呼び出し
a=a_function(1, 2)
a=a_function(arg2=2, arg1=1)
モジュールの活用
いろいろなライブラリ(テキスト処理/ネットワーク/数値計算など)を活用する為に、モジュールを利用する。
モジュールのインポート
import re from urllib import urlopen
- モジュールのインポートはどこでもできる。関数やif文などのブロックでもおk(普通はやらないよなぁ)
- インポートしたモジュールは、変数や関数と同じようにオブジェクトとして扱える
- 名前空間内でインポートしたモジュールは、その名前空間でしか使えない
モジュールの作成
- Pythonコードを書いたソースファイル=スクリプトファイルである。このスクリプトファイルをモジュールとして扱う。
- スクリプトファイルのファイル名がモジュール名になる
- a_module.pyというファイルにsome_func()という関数を記述すると、以下のように利用できる
import a_module # モジュールをimportする場合 a_module.some_func() from a_module import some_func() # 関数だけをimportする場合 some_func()
Pythonのオブジェクト指向機能
- Pythonは純粋オブジェクト指向言語
- ただ、Pythonはオブジェクト指向機能の利用を強制しない作りになっている。無理に使おうとせず、必要に応じて利用するのが流儀
- Pythonはすべてがオブジェクト。文字列/リストやモジュール/クラス/関数/メソッドまでもオブジェクトとして利用可能
- 関数やクラスを変数に代入したり、挙動を動的に変更できる
クラスを定義する
class SomeClass: def __init__(self, num): """初期化メソッド""" self.num=num def some_method(self, param): """メンバ変数と引数をかけ算して返す""" return self.num*param
- クラスにはメソッドやアトリビュート(メンバ変数)を定義可
- プライベートメソッドは定義できない。すべてバーチャルな公開メソッドとなる。メソッドを外部から隠蔽するには、クラス名の前に(メソッド名の前にの間違い?)アンダースコア(_)を1つまたは2つ付ける
クラスインスタンスの生成
ins=SomeClass()
ins.some_method(10)
第1引数self
- Pythonのメソッドには、第1引数として「self」を定義しておく。この引数には、クラスのインスタンスオブジェクト自体が暗黙に渡される
- 代入すると変数が定義されるように、インスタンスオブジェクトのアトリビュート(メンバ変数)に代入すると新しいアトリビュートが作られる。初期化メソッドであらかじめ定義しておきたいアトリビュートに代入を行い、アトリビュートの初期化を行えば良い
特殊メソッド
- Pythonには、アンダースコア2つで始まるメソッドが何種類か利用できる。
- このようなメソッドは特殊メソッドと呼ばれる
- 初期化メソッド__init()__も特殊メソッドの一種
- 特殊メソッドを使うと、演算子やシーケンスのインデックスや辞書型キーを使ったアクセス、アトリビュートへのアクセスといった言語の基本的な機能をオーバーライドできる
おなかすいた
特売のバナナたべよう。今日はこれぐらいで終わり!
2008-06-27
Pythonのお勉強私的メモ(その1・基本以前・起動終了組み込み型)
Pythonのお勉強シリーズ | |
Pythonのお勉強を開始!その内容をメモっていこうと思います。とりあえずWebに書き出す事でやる気を維持するのが魂胆です。
超初心者の勉強メモだからなんの参考にもなりません!読んでもPythonのお勉強ができる訳ではありません!ぐぐるから間違えてきちゃった人は戻った方がいいと思う!
- 作者: 柴田淳
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2007/11/30
- メディア: 単行本
- 購入: 4人 クリック: 171回
- この商品を含むブログ (37件) を見る
昨日届きました!買ってから気がついたけど、どうやら↓の本と間違えて注文してた!
- 作者: 柴田淳
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/08/22
- メディア: 単行本
- 購入: 11人 クリック: 508回
- この商品を含むブログ (181件) を見る
買っちまったもんはしょうがないから、とりあえずこれで勉強することにしたよ。(なんとかなる!)
Macには最初からPythonが入っているから、インストールは省略しました。
Pythonコマンドインタプリタを起動する
$ python Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
Pythonのプロンプト「>>>」が表示され、Pythonスクリプトが入力可能になる。
Pythonコマンドインタプリタを終了する
>>> exit() $
Pythonの組み込み型
「組み込み型」って何の事だろと思ったら、ただの型だけど、あらかじめすぐに利用できるというような意味で「組み込み型(ビルトイン型)」なんだって。にゃ?。よくわかんないけど型なのな
以下の種類があるらしい
- 数値型
- 整数型
- 浮動小数点型
123, 3.14
きをつけなきゃいけないのは、Pythonでは計算結果の数値の精度を維持するから、1/2は0.5じゃなくて0なんだって。覚えておく
- 文字列型
ダブル「"」、シングル「'」どっちの引用子もおk。あと引用子は1つでも3つでもおk(なんでだろ)
文字列は「シーケンス型」と呼ばれるデータ型の一種でもあって、インデックスやスライス(部分取り出しみたいなものか?)によるアクセスが可能
u"日本語"
コデックス(codecs コーデックスじゃなくてコデックスって書いてある。なんでだろー)という仕組みを使う事で、他のエンコードへも変換可能
さらに、2.4以上のPythonでは日本語のエンコードを扱う「CJK Codecs」が標準搭載されている。便利!らしい
- リスト
>>> a_list = [100, 200, "abc"] >>> print a_list [100, 200, 'abc'] >>> print a_list[0] 100
インデックスは0から数える。
スライスって機能があって。指定した区間をリストとして取り出せる。
>>> print a_list[2:3] ['abc']
スライスの最後の要素番号(ここではインデックス3、要素位置4)は含まれない
代入で中身変更
>>> a_list[0] = 101 >>> print a_list [101, 200, 'abc']
- 辞書(ディクショナリ)
Mapみたいなもの?要素をキーで管理
>>> b_list = {'one':1, 'tow':2}
>>> print b_list
{'tow': 2, 'one': 1}
>>> print b_list['one']
1
間違えたキーを指定するとKeyError
>>> print b_list['hatena'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'hatena'
あらたな要素を追加するには、代入
>>> b_list['three'] = 3
>>> print b_list
{'three': 3, 'tow': 2, 'one': 1}
キーがなければ新たなキーが作成される。キーがある場合は要素だけ入れ替え
- タプル型
リストと一緒だけど、変更できない。変更するとエラー
>>> c_list = (100, 200, "cde") >>> print c_list (100, 200, 'cde') >>> c_list[0] = 101 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
- その他の組み込み型
- ファイル型 ファイルを扱えるらしい
- 集合型 set型とも呼ばれる。リストのようなシーケンスのデータ型だが、要素の中身が重複されないように保たれる。へー
あと、文字列のパターン検索を行う正規表現は組み込み型として用意されてないから、別途モジュールをインポートする必要があるって!にゃ?よくわからないけどいいや。
おなかすいた
とりあえずお勉強その1はここまで、ちょっとラーメン食ってくるお
2008-06-26
MacのVimでPythonコード書く時のTABの設定
~/.vimrcに
:autocmd FileType python setlocal tabstop=4 shiftwidth=4 expandtab
と書いてみた
※setlocalの所をsetと間違って書いてました。ka-nachtさんよりコメントで指摘して頂きました!ありがとうございます!

○setlocal
さっそく修正しました!