2015/04/28

Python Tips: Python で簡易サーバを走らせる

Python で簡易サーバを走らせる方法をご紹介します。

ターミナルからの python コマンドでサーバを立ち上げることができます。
Python 2 と Python 3 では組み込みのライブラリの構成が異なっているためコマンドが若干異なります。

Python 2


python2.7 -m SimpleHTTPServer 8080


Python 3


python -m http.server 8080



いずれも末尾の 8080 の部分はポート番号です。このサンプルでは 8080 としていますが特に 8080 である必要はなく、利用したいポート番号を指定することができます。ポート番号を省略した場合はいずれも 8000 がデフォルトで選択されるようになっています。

2015/04/24

Python Tips:string の format 内で {} を出力したい

Python の format で {} を出力する方法をご紹介します。

まず python の format とは何のことを言っているかといいますと、次の文字列の format メソッドのことを指しています。

print('hello, {}'.format('world'))  # => hello world
print('hello, {}'.format('goodbye'))  # => hello goodbye

フォーマットのテンプレートとなる文字列内では、変数のプレースホルダとして {} を使うことになっています。ですので、次のような形で {} を使おうと思ってもエラーが発生してしまいます。

print('I like ruby block syntax like: {:d}.times { |i| puts i }'.format(5))
# => KeyError Traceback (most recent call last)
# KeyError: ' |i| puts i '

プレースホルダではなく通常の文字として {} を使いたい場合には、記号をふたつ重ねて {{ か }} を使います。

print('I like ruby block syntax like: {:d}.times {{ |i| puts i }}'.format(5))
# => I like ruby block syntax like: 5.times { |i| puts i }

以上です。

その他 format にはパッと見では把握しきれないくらい豊富なオプションが用意されているので、詳しく知りたい方は公式ドキュメントの方にあたってみてください。


参考
- フォーマットのシンタックス - Python 公式ドキュメント
- フォーマットの例 - Python 公式ドキュメント
- Python format throws KeyError - Stack Overflow

2015/04/15

Python Tips:バイセクションサーチを行いたい

Python でバイセクションサーチ(二分探索法)を行う方法をご紹介します。

Python にはそのままずばり「 bisect 」――バイセクションサーチを行うためのライブラリが用意されています。

実際の使い方を見てみましょう。

from bisect import bisect_left, bisect_right

li = [1, 3, 5, 6, 10, 14, 17, 22, 30, 35]

index_left = bisect_left(li, 6)  # => 3
index_right = bisect_right(li, 6)  # => 4

bisect_left bisect_right はソート済みのリストに新たな値を入れようとしたときに、入れるべき場所を返してくれる関数です。新たな値がすでにリストに存在する場合には、 bisect_left はなるべく左側に、 bisect_right はなるべく右側に入れようとします。

上記の例では 6 を追加するなら、入れるべき場所は次のふたつのうちのどちらかです。

[1, 3, 5, __here__, 6, 10]
[1, 3, 5, 6, __here__, 10]

上の場合のインデックスは 3 、下の場合のインデックスは 4 で、それぞれ bisect_left 、 bisect_right の戻り値が示すものと一致します。

さらに bisect_left bisect_right には範囲を制限するための引数を渡すこともできます。こんな感じ。

bisect_left(対象リスト, 探したい値, lo=左側のインデックス, hi=右側のインデックス)

実際に二分探索の結果、値を挿入したい場合には insort_left insort_right を使います。

from bisect import insort_left

bisect.insort_left(li, new_element)

insort_left insoft_right はいずれも引数に与えたリストを変更する(破壊的な)メソッドです。


参考
bisect — Array bisection algorithm - Python 公式ドキュメント

2015/04/09

Python Tips:文字列を検索したい

Python Tips:文字列を検索したい


Python で文字列を検索する方法をご紹介します。

ここでは 2 つの方法をご紹介します。ひとつは「文字列型」のメソッドを使う最もシンプルな方法、もうひとつは「正規表現」を使う方法です。

  1. 文字列型のメソッドを方法
  2. 正規表現を使う方法

1. 文字列型のメソッドを方法


まずは文字列型のメソッドを使う方法を見てみましょう。インデックスを取得したい場合には find を、もっと単純に部分文字列の有無だけを判定したい場合には in キーワードを使います。

find を使う

s = 'hello kyoto'
print(s.find('kyo'))  # => 6
print(s.find('tokyo'))  # => -1

文字列のメソッド find は、引数に渡されたパターンが最初に現れるインデックスを返します。マッチしなかった場合には -1 を返してくれます。

ちなみに、検索を文字列の末尾から行いたい場合には同等の rfind メソッドを使うとよいでしょう。

s = "hello kyoto"
print(s.find('o'))  # => 4
print(s.rfind('o'))  # => 10

find についてはこの他にも検索開始のインデックスを指定するような使い方もできるので、より詳しいところを知りたい方は次のページをご参照ください。

string.find - Python 公式ドキュメント

単純に部分文字列の有無だけをチェックしたい場合には in キーワードがより直感的で便利です。

print('hell' in 'hello kyoto')  # => True
print('heaven' in 'hello kyoto')  # => False

正規表現を使うまでもないシンプルなケースではこの find か in を使う方法を採るとよいかと思います。


2. 正規表現を使う方法


もうひとつ、「正規表現」を使う方法を見てみましょう。

Python で正規表現を使うには re ライブラリを使用します。マッチした文字列をそのまま取得したい場合は関数 findall を使うとよいでしょう。

import re

print(re.findall('o.', 'hello world'))  # => ['o ', 'or']
print(re.findall('ohayo', 'hello world'))  # => []

マッチしたパターンが存在しない場合は空のリストが返ってきます。ちなみに、 findall は結果をそのままリストに展開した状態で返しますが、 finditer という関数を使えばリストではなくイテレータとして結果を取得することができます。

マッチした結果をいろいろと使い回したい場合には search などの関数を使えば「正規表現マッチオブジェクト」を生成して使うとよいでしょう。

import re

result = re.search('l+', 'hello world')
print(result.span())  # => (2, 4)
print(result.start())  # => 2
print(result.end())  # => 4

find や in を使った通常の文字列検索では物足りない場合にはこちらの正規表現を使うとよろしいかと思います。

以上です。


参考
ライブラリ:re