python Tips

ここには python を使用していく上で便利な Tips をメモしておきます.

基本的には何かのサイトを参考にしているので,参考元を参照したい場合, このページの下の参考リストを確認ください.

python 環境に関して

python をローカルで使用している場合には 大抵 sudo (管理者) 権限を持っているので,好きなようにライブラリを使えますが, サーバーを使用しているとそうでもない場合も多いかと思います.

このような場合,以下のように pip を使用すると結構幸せになれます.

pip –user
$ pip install -U hogehoge --user

このようにした場合,.local にライブラリ関連が置かれるので, ~/.local/bin にパス を通したり,PYTHONPATH を設定して置くと便利です.

for 文関係

整数のループ

例えば 0 ~ 9 までの値でループを回す場合,以下のように記述します.

>>> for i in range(10):
>>>     print i
0
1
2
3
4
5
6
7
8
9

注釈

range() について

上記の例に出てきた range 関数はデフォルトでは 0 から与えられた値 -1 までの リストを返します.最大値が引数から 1 引いたものであることに注意してください.

この range() は複数の引数をとることができます. たとえば,最小値を 0 ではなく他の値にしたい場合以下のように記述できます.:

>>> range(2, 10)
[2, 3, 4, 5, 6, 7, 8, 9]

またある値おきのリストを作成することも可能です. 例えば 1 ~ 9 までの数値を 2 ごとにリストにしたい場合,以下のように記述します:

>>> range(1, 10, 2)
[1, 3, 5, 7, 9]

上記の例は与える引数が小さい場合問題にならないのですが, i の値がとてつもなく大きい場合,メモリを消費しすぎるという問題があります. これを回避するためには xrange() を使用します.

>>> for i in xrange(9):
>>>     print i
0
1
2
3
4
5
6
7
8
9

xrange は一気にメモリを確保しないためメモリの節約が可能です.

  • python 3 系を使用している場合,range(), xrange() の挙動は一緒であるらしいです.

コレクション

python の for 文は他の言語で言うところの forEach 文の挙動を行います. これはリストなどの要素をループ中に取得したい場合に便利です.

>>> strs = ['hoge','foo', 'piyo']
>>> for str in strs:
>>> print str
hoge
foo
piyo

一般的なお作法として for 文では複数形と単数形で 何をループされているのかをわかりやすくするようです.

逆順でループを回したい場合, reversed() を使用すると便利です.

>>> strs = ['hoge','foo', 'piyo']
>>> for str in reversed(strs):
>>>     print str
piyo
foo
hoge

コレクションのループと要素番号の取得

コレクションの要素と一緒に要素番号も取得したい場合は割とよくあることかと思います. 上記のような需要は以下のような記述で解決できます.

>>> strs = ['hoge','foo', 'piyo']
>>> for i, str in enumerate(strs):
>>>     print i, '-->' , str
0 --> hoge
1 --> foo
2 --> piyo

2つのコレクションのループ

二つのリストから同じ要素番号の要素を取ってきて、要素数が少ない方に合わせてループ を終了したいというパターンです。

>>> names = ['raymond', 'rachel', 'mattew']
>>> colors = ['red', 'green', 'blue', 'yellow']
>>> for name, color in zip(names, colors):
>>>     print name, '-->', color
raymond --> red
rachel --> green
mattew --> blue

一方ですべての組み合わせを取得したい場合以下のようにすると便利です.

>>> import itertools
>>> names = ('raymond', 'rachel', 'mattew')
>>> colors = ('red', 'green', 'blue', 'yellow')
>>> for name, colour in itertools.product(names, colors):
>>>     print '%s => %s' % (name, color)
raymond => red
raymond => green
raymond => blue
raymond => yellow
rachel => red
rachel => green
rachel => blue
rachel => yellow
mattew => red
mattew => green
mattew => blue
mattew => yellow

クラス

オブジェクトのようにアクセスできる辞書

表現が正しいか不明ですが要は Pandas ライブラリの DataFrame や Series のように あとから任意の変数名で呼び出せるリストを持つクラスを作成したい場合の Tips です.

多分実例を見ていただくのが早いでしょう.

>>> class Hoge(dict):
>>>     def __getattr__(self, name):
>>>        return self[name]
>>>     def __setattr__(self, name, value):
>>>        self[name] = value

このようなクラスを作成します. このクラスは以下のように要素を増やすことが可能です.

>>> obj = Dict
>>> print obj
{}
>>> obj.name = 'foo'
>>> print(obj)
{'name': 'foo'}
>>> print(obj.name)
foo

これは複数の(しかし数の固定ではない)リストを整理したい場合に便利ではないでしょうか?

動的にプロパティを決める

上記のやり方は辞書を前提にしたものですが, こちらはより一般的なやり方です.

動的にプロパティを決める
class Sample(object):

    def add(self, key, value):
        self.__dict__[key] = value

if __name__ == "__main__":
    s = Sample()
    # testというキーで値を設定する。
    s.add('test', 'testの値')
    print s.test
    # 値を変更してみる。
    s.test = '変更'
    print s.test

ちなみにメゾットを動的に決める場合には __dict__ を使用します.

動的にメゾットを決める
 class Sample(object):

     def add_function(self, name, func):
         self.__dict__[name] = func

 def func_1():
     print 'hello'

 def func_2(name):
     print 'hello ' + name


if __name__ == "__main__":
    s = Sample()
    s.add_function('say_hello', func_1)
    s.add_function('say_hello_with_name', func_2)
    s.say_hello()
    s.say_hello_with_name('symfo')

日付データ

誕生日から現在の年齢,月齢を計算する

>>> import datetime
>>> from dateutil import relativedelta


>>> now = datetime.datetime.now()
>>> date = datetime.datetime(2013, 2, 3)
>>> age = relativedelta.relativedelta(now, date)
>>> age.years  # 年齢を表示
1
>>> age.months  # 月齢を表示
9

文字列

全角数値を半角数値に変更する

unicodedata というライブラリ(標準ライブラリの一つです)を使用すると簡単にできま す.unicodeにはもともと、対応する文字が登録されてるらしいです. 例えば以下のように使用します.

>>> import unicodedata
>>> str = u'1'
>>> result = unicodedata.normalize('NFKC', str)
>>> print result
1

数字(文字列)の頭に0を付ける

数値データを文字列に変換する際に頭に0をつけて位の数を統一したい場合が (残念ながら)存在します.このような際には以下のようにするのが簡単です.

>>> print '1'.zfill(2)
01
>>> print '1'.zfill(3)
001

落ち穂拾い

ファイルの読み書き

一番基本的な方法に関して 書いて行きます.

以下のサンプルでファイルの読み込みが可能です.

>>> for line in open('text.txt', 'r'):
>>>     print line