はてブロ@ama_ch

https://twitter.com/ama_ch

今日のPython

if文と組み込み型

inを使ってオブジェクトの要素を調べる

p.156

>>> s = "hello,mynameisama-ch."
>>> if "name" in s:  #文字列の要素を検索
...     print "name is found!"
... 
name is found!
>>> list = [1, 2, 3, 4]
>>> if 3 in list:  #リストの要素を検索
...     print "found!"
... 
found!
>>> if [1, 2] in list:  #リストの要素にリスト[1, 2]があるか
...     print "found!"
... 
>>>                     #ない


辞書のキーや値を確認する
p.156

>>> if "title" in dict:  #辞書のキーを検索
...     #処理
>>> if dict.has_key("title"):  #上と同じ。古いPythonとの後方互換を持つ
...     #処理
>>> if "test" in dict.values():  #辞書の値を検索
...     #処理
range()関数を使いこなす

p.159

>>> range(5)  #0から4
[0, 1, 2, 3, 4]
>>> range(10, 15)  #10から14
[10, 11, 12, 13, 14]
>>> range(10, 21, 2)  #10から20まで、2ずつ増加
[10, 12, 14, 16, 18, 20]
>>> range(21, 10, -1)  #21から11まで、1ずつ減少
[21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11]
シーケンスとループカウンタ

p.161

>>> seq = ["hello", "my", "name", "is", "ama-ch"]
>>> for cnt,item in enumerate(seq):
...     print cnt, item
... 
0 hello
1 my
2 name
3 is
4 ama-ch

enumerate()という組み込み関数を使うことで、スマートにループカウンタを使った処理が書ける。
enumerate()は2つの要素をタプルにして次々に返す。最初の要素はループカウンタに相当する数値で、0から始まる。2つ目の要素はシーケンスの中の要素。

二つのシーケンスを使ったループ

p.162

>>> s1 = [1, 2, 3, 4, 5]
>>> s2 = ['a', 'b', 'c', 'd']
>>> zip(s1, s2)
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
>>> for num, item in zip(s1, s2):
...     print num, item
... 
1 a
2 b
3 c
4 d

組み込み関数zip()は、2つのシーケンスを引数として渡し、2つのシーケンスから要素を順番に取り出し、2つの要素を持つタプルを作る。この処理を、どちらかのシーケンスがなくなるまで続ける。

関数で引数リストを受け取る

p.165
関数に与える引数の前にアスタリスク(*)をつけると、キーワードを指定しない引数を何個でも受け付けることができる。

>>> def foo(a, b, *vals):
...     print a, b, vals
... 
>>> foo(1, 2, 3, 4, 5)
1 2 (3, 4, 5)  #変数valsにタプルとして代入される
>>> foo(1, 2, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'c'

キーワード指定しないとvalsにタプルとして代入されるが、c=3のようにキーワード指定をすると、関数側でそのキーワードを持っていないのでエラーとなる。

関数でキーワード引数を受け取る

p.166
アスタリスクを2個つけた引数を定義すると、キーワード指定された未定義の引数を受け取れるようになる。

>>> def bar(a, b, **args):
...     print a, b, args
... 
>>> bar(1, 2, c=3, d=4)
1 2 {'c': 3, 'd': 4}

c,dの未定義の引数は、argsという変数に辞書として代入される。
アスタリスク(*)つき引数の定義は、引数リストの最後に書く。

Pythonと日本語

8ビット文字列からユニコード文字列を得る

p.176

>>> u = unicode(s, "euc-jp", "strict")  #EUC-JPの文字列を変換
>>> u = s.decode("shift-jis", "ignore")  #シフトJISをユニコードに変換

組み込み関数unicode()かdecode()を使うことで、8ビット文字列をユニコードに変換できる。
前者の例では、変数sに入った文字列をEUC-JPの8ビット文字列と見なし、ユニコード文字列に変換する。


p.177 Pythonで利用できるエンコード

エンコード Pythonエンコード
シフトJIS sjift-jis, shift_jis, sjis
ISO-20220JP(JIS) iso-20220jp
EUC-JP euc-jp
UTF-8 utf-8


p.177 変換エラーへの対処を指定する文字列

文字列 説明
strict エラー(例外)を発生して変換を停止する。オプションを指定しない場合のデフォルトの振る舞いもこれ。
replace エンコード変換できない文字があると、"?"などの適切な文字列に置き換えて返す。
ignore エラーが起こった場合、そのまま変換を継続する。変換できなかった文字列は取り除かれる。
ファイルから文字列を読み込む

codecsモジュールのopen()関数を使うことで、便利にユニコード文字列を取り出すことができる。これはファイルオブジェクトを返す組み込み関数のopen()と同じように利用するが、エンコーディングやエラーへの対処文字列を引数に指定できる。


p.182 codecsモジュールのopen()関数を使う

>>> import codecs  #codecsをインポートする
>>>   #エンコードを指定してファイルを開く
>>> uf = codecs.open("jpwords.txt", "r", "utf-8")
>>> for uline in uf.readlines():  #ファイルを1行ずつ読み込む
...     print uline,              #1行ずつ表示する
... 
こんにちはこんにちは!
僕の名前はama-chです。
ヨロシクね。○×→☆
ファイル名の扱い

以下のコードで、システムが使用しているファイル名のエンコーディングを調べられる。

>>> import sys
>>> sys.getfilesystemencoding()
'utf-8'

OS X 10.5.2はutf-8を使用します!
PyKfって使った方が良いんだろうか・・・アドレスにアクセスしても繋がらないし、これから必要だと思ったら探す。


p.186 Pythonに設定されてるデフォルトエンコーディングを調べる

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

これをutf-8に変えたいんだけど、sitecustomize.pyを置く場所がわからない・・・site-packagesなんてディレクトリがない・・・