Lif_の無職日記

2008-06-30

Pythonのお勉強私的メモ(その3・基本以前・ユニコードと日本語処理/復習1 環境・文字列・リスト・フロー制御・リスト詳細・del文・ループのテクニック)

| 19:12 | Pythonのお勉強私的メモ(その3・基本以前・ユニコードと日本語処理/復習1 環境・文字列・リスト・フロー制御・リスト詳細・del文・ループのテクニック)を含むブックマーク

第3回。今日も曇ってて温度低めで過ごしやすい。引き続きお勉強。

これは超初心者の勉強メモだからなんの参考にもなりません!読んでもPythonのお勉強ができる訳ではありません!ぐぐるから間違えてきちゃった人は戻った方がいいよ!

ユニコードと日本語処理

コデックス
ユニコード型と日本語の境界

マルチバイト文字列の区切りを容易に扱える。便利

>>> u=u"あいうabc"
>>> print u[2]
う

インデックス2の文字を読み出すと、ちゃんと3番目が返ってくる。

同じことをユニコード相当の8ビット文字列でやると

>>> ru="あいうabc"
>>> print ru[2]

インデックス2の文字を読み出すので、「あ」の3バイト目(元文字はUnicodeだから1文字あたり3バイト使ってる)が返ってくる。

他のエンコードからユニコード文字列への変換
u=unicode('あいう','euc-jp','replace') 

unicode()関数を使う

第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 節
  • breakとcontinuec言語と一緒の動きをする
  • ループ文はelse節を持つ事ができる。else句はループが終了したときに実行されるが、breakで中断した場合には実行されない
>>> 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-29

3日坊主

18:28 | 3日坊主を含むブックマーク

あーやる気でないー。今日はお勉強お休みだ。日曜だし

ビデオニュースが配信されていたので見る。「死ぬか殺すかまで若者を追いつめる労働現場の現実とは」 今回のゲストは雨宮処凛氏。

うートヨタ怖い。他人事じゃない。おいらもプログラマ職以外能無しだ。仕事さがさなきゃいけないなぁ。はぁ

午後は近所のスーパーで食料を買い込み。今日は久しぶりに魚を食うことにする。

珈琲豆が切れていたのでさらに買い出し。すごい雨だ。でも温度低くてすごしやすい。

2008-06-28

Pythonのお勉強私的メモ(その2・基本以前・フロー制御/関数/モジュール/オブジェクト指向)

| 13:30 | Pythonのお勉強私的メモ(その2・基本以前・フロー制御/関数/モジュール/オブジェクト指向)を含むブックマーク

第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)"
  • pythonにはスイッチ文がない
  • 論理式はandやor
  • elifあり
  • 比較演算子は==や<など
  • 空の文字列や空のリスト、空の辞書は偽(False)として扱う
シーケンスを使った繰り返し(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 a_function(arg=10):
  • 「*param」のようにアスタリスク(*)を使った場合、特殊な意味を持つ。定義されている数以上の引数を渡して関数を呼び出すと、あふれた引数がリストとしてparam引数に入る
def a_function(*param):
def a_function(**args):
関数戻り値とアンパック代入
  • リターン文はreturn
  • 複数のデータを一度に戻り値として返却できる(アンパック代入と呼ぶ)
return a,b,c
#---
a,b,c=somefunc()
関数名前空間
関数の呼び出し
a=a_function(1, 2)
  • 戻り値がない場合は「None」と呼ばれる特別な値が返る(Nullみたいなもんか?)
  • 引数の指定方法は上記みたいな方法以外に、変数名をキーワード指定することもできる。定義順に関係なく引数を指定できる
a=a_function(arg2=2, arg1=1)

モジュールの活用

いろいろなライブラリ(テキスト処理/ネットワーク数値計算など)を活用する為に、モジュールを利用する。

モジュールインポート
import re
from urllib import urlopen
モジュールの作成
import a_module      # モジュールをimportする場合
a_module.some_func()

from a_module import some_func()    # 関数だけをimportする場合
some_func()

Pythonオブジェクト指向機能

クラスを定義する
  • class文で定義
  • 既存のクラスを継承するには、class名の後に括弧を添えて継承するクラス名を記述する。多重継承する場合は、カンマ(,)で区切る。
  • 組み込み型を含むすべての型やクラスを継承できる
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
特殊メソッド

おなかすいた

特売のバナナたべよう。今日はこれぐらいで終わり!

2008-06-27

Pythonのお勉強私的メモ(その1・基本以前・起動終了組み込み型)

| 12:25 | Pythonのお勉強私的メモ(その1・基本以前・起動終了組み込み型)を含むブックマーク

Pythonのお勉強を開始!その内容をメモっていこうと思います。とりあえずWebに書き出す事でやる気を維持するのが魂胆です。

超初心者の勉強メモだからなんの参考にもなりません!読んでもPythonのお勉強ができる訳ではありません!ぐぐるから間違えてきちゃった人は戻った方がいいと思う!

とりあえずPythonの本をAmazonで買いました!

みんなのPython Webアプリ編 [みんなのシリーズ]

みんなのPython Webアプリ編 [みんなのシリーズ]

昨日届きました!買ってから気がついたけど、どうやら↓の本と間違えて注文してた!

みんなのPython

みんなのPython

買っちまったもんはしょうがないから、とりあえずこれで勉強することにしたよ。(なんとかなる!)

Macには最初からPythonが入っているから、インストールは省略しました。

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()」と入力する

>>> exit()
$

Pythonの組み込み型

「組み込み型」って何の事だろと思ったら、ただの型だけど、あらかじめすぐに利用できるというような意味で「組み込み型(ビルトイン型)」なんだって。にゃ?。よくわかんないけど型なのな

以下の種類があるらしい

  • 数値型
    • 整数
    • 浮動小数点型
123, 3.14

きをつけなきゃいけないのは、Pythonでは計算結果の数値の精度を維持するから、1/2は0.5じゃなくて0なんだって。覚えておく

ダブル「"」、シングル「'」どっちの引用子もおk。あと引用子は1つでも3つでもおk(なんでだろ)

文字列は「シーケンス型」と呼ばれるデータ型の一種でもあって、インデックスやスライス(部分取り出しみたいなものか?)によるアクセスが可能

文字列型のあたまに「u」付けるとUnicodeになります

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の設定

20:37 | MacのVimでPythonコード書く時のTABの設定を含むブックマーク

~/.vimrcに

:autocmd FileType python setlocal tabstop=4 shiftwidth=4 expandtab

と書いてみた

※setlocalの所をsetと間違って書いてました。ka-nachtさんよりコメントで指摘して頂きました!ありがとうございます!

ka-nachtka-nacht 2008/06/26 21:00 ×set
○setlocal

LifLif 2008/06/26 21:01 わ!ありがとうございます!
さっそく修正しました!