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 で文字列を検索する方法をご紹介してみます。

ここでは 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() は第 2 引数、第 3 引数を指定することで検索範囲を絞り込むことができたりもするので、詳しい使い方に興味のある方は公式ページをご覧になってみてください。

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

一致箇所までは知る必要がなくて、単純に対象のパターンが存在するかどうかだけをチェックしたい場合には in キーワードを使うとよいでしょう。

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

これは文章としてなんだか自然な感じで可読性も高いので、 in で事足りるケースではできるだけ in を使うのがよいでしょう。

正規表現を使う必要がないシンプルなケースではこの 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()match() などの関数が便利な「正規表現マッチオブジェクト」を返してくれるので、それらを使うようにするとよいでしょう。

import re

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

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

以上です。


参考
ライブラリ:re