辞書の値によってキーを削除する

例えば、こんな辞書があったとする。

>>> dic = {'Andy': 27, 'Bill': 32, 'Charlie': 24}

この辞書から、値が 30 を超えるキー(つまり ‘Bill’)を削除したい。こうすると:

>>> for k in dic:
...     if dic[k] > 30:
...         del(dic[k])
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

エラーになる(イテレーションの最中に辞書のサイズが変わってるって怒られる)。
でもキーは削除されてる。

>>> dic
{'Charlie': 24, 'Andy': 27}

なんでだかは解らない。
エラーが出ないようにするには items() メソッドを使えばいい。今度は値が 25 を超えるキーを削除してみる。

>>> for k, v in dic.items():
...     if v > 25:
...         del(dic[k])
...
>>> dic
{'Charlie': 24}

無事に消えた。

Pythonの軽量Webフレームワークbottleを使ってみる(2)

テンプレートについて補足。
昨日のスクリプトでは、template 関数の引数に直接テンプレートを文字列として渡していた。短いテンプレートならそれでもいいけど、引数として文字列で渡すには長すぎるのが普通だ。そこで、テンプレートそのものじゃなく、名前で指定できるようになっている。
テンプレートは、スクリプトと同じディレクトリの下に views という名前でディレクトリを作って、その中に入れておく。そうすると bottle がテンプレートを見つけて読み込んでくれる。
次のスクリプトでは info という名前のテンプレートを使っている。

# encoding: utf-8

from bottle import route, request, template, run

@route('/')
def index():
    return "<a href="\&quot;./info\&quot;">Link</a>"

@route('/info')
def info():
    ip = request.environ.get('REMOTE_ADDR')
    referer = request.headers.get('Referer') or ''
    return template("info", ip=ip, referer=referer)

run(host='localhost', port='8080', debug=True, reloader=True)

で、テンプレートのほうはこう。

<h1>Remote information</h1>
IP address: {{ip}}

Referer: {{referer}}