2012-11-01
■10月の読書メーター
読んだ本の数:12冊
読んだページ数:3381ページ
ナイス数:12ナイス
OUT OF CONTROL (ハヤカワ文庫JA)の感想
「まあこ」と「箱」は異形コレクションで既読。「箱」は題名だけでストーリーラインを思い出せる程度に印象が残っていた。やっぱり面白い。「まあこ」は取り出して読むと面白いのだけど、異形コレクションの中では……。そういや全体的に今ひとつの巻だったかも。「メトセラとプラスチックと太陽の臓器」が面白い。「OUT OF CONTROL」はすごくよくできていて、何度も読める作品なんじゃないかという予感。「スタンド・アウト」は興味深い。「デストピア」は半端。「日本改暦事情」は今となっては"天地明察を読め!"という気分。
読了日:10月31日 著者:冲方 丁
2000年のゲーム・キッズ(上) (星海社文庫)
読了日:10月22日 著者:渡辺 浩弐,竹
暗黒太陽の浮気娘 (ミステリアス・プレス文庫―ハヤカワ文庫 (10))の感想
話の筋として知ってはいたけど、D&Dのプレイングの最中に犯人をあぶりだすミステリって……変。SFファン(作中表現を尊重してオタクとは書かない)の生態が楽しい。今は有名な《プラン9・フロム・アウタースペース》が《外宇宙からの第九次侵略計画》として名前だけ登場。ここのやりとり「あら、見なきゃだめよ! 信じられないくらいひどいんだから」は可笑しい。(《マウス・オブ・マッドネス》でモーテルのテレビに映っていた)《ロボット・モンスター》は《怪物ロボット》だったり。D&Dのプレイ中に出てきた変化(へんげ)ってなに?
読了日:10月19日 著者:シャーリン・マクラム
カンナ 京都の霊前 (講談社ノベルス)の感想
あっさりとした解決。QEDの、日本史の話をしていたと思ったらミステリの謎に繋がってました、というフォーマットに縛られていない分こちらの方が好き。日本史の話で盛り上がってお仕舞いでokなので。
読了日:10月15日 著者:高田 崇史
カンナ 出雲の顕在 (講談社ノベルス)
読了日:10月15日 著者:高田 崇史
カンナ 天満の葬列 (講談社ノベルス)の感想
道真公の生前が悪霊のイメージからはほど遠いというのは永井路子の悪霊列伝などでも既知。悪霊列伝では寺社の権力(?)争いに求めていたかなー。こちらの解釈の方が面白い。
読了日:10月15日 著者:高田 崇史
カンナ 鎌倉の血陣 (講談社ノベルス)
読了日:10月14日 著者:高田 崇史
カンナ 戸隠の殺皆 (講談社ノベルス)
読了日:10月14日 著者:高田 崇史
カンナ 奥州の覇者 (講談社ノベルス)
読了日:10月12日 著者:高田 崇史
カンナ 吉野の暗闘 (講談社ノベルス)
読了日:10月10日 著者:高田 崇史
クトゥルフ神話への招待 ~遊星からの物体X (扶桑社ミステリー)
読了日:10月9日 著者:J・W・キャンベルJr.,H・P・ラヴクラフト,ラムジー・キャンベル
復興の書店の感想
もう震災関連の書籍は読まなくても、と思っていたがこんなものを見つけた日には手に取らずにいられない。p40「生活に必要な食料や水を買い求めるためにスーパーに並んだ人たちが、同じようにその足で書店にも並んでいるんですよ」本屋の開店も、新刊の配本も、図書館の再開も、みな待ち遠しかった。本屋さんは私にとっての日常の象徴だった。この本を読んで、あらためてそう思う。一頁堂書店さんが、みんな全くの素人というのは意外だった。巻頭の地図が位置がよく把握できるのでよかった。
読了日:10月8日 著者:稲泉 連
2012-11-07
■SonyMusicのアーティストの取り扱い開始
と聞いて、さっそく探してみる。
ルミナス - EP - Claris
ひかりふる - EP - Kalafina
あったあった。
つい数日前に買おうか考えてやめたのだった。
……探してしまう自分がなんだかなぁ。
2012-11-11
■このあたりもiTSに入ってきてた
TBS系TVアニメーション「アイドルマスター」オープニング・テーマ 《通常盤》 - EP - 765PRO ALLSTARS
THE IDOLM@STER TVシリーズ 新オープニング・テーマ シングル 《通常盤》 - EP - Various Artists
TVアニメ「アイドルマスター」 劇中歌 COLLECTION -FIRST SEASON- - Various Artists
TVアニメ「アイドルマスター」 ENDING COLLECTION -FIRST SEASON- - Various Artists
TVアニメ「アイドルマスター」 劇中歌 COLLECTION -SECOND SEASON- - Various Artists
TVアニメ「アイドルマスター」 ENDING COLLECTION -SECOND SEASON- - Various Artists
2012-11-14
■datetime型のタイムゾーン変換
の正着はなんだろうか。
とりあえず、naiveなdatetimeインスタンス(UTC相当の時刻)から、awareなdatetimeを持ってくるのに、
> pip install pytz
を使って、
import pytz utc=pytz.timezone('UTC') jst=pytz.timezone('Asia/Tokyo') aware = naive.replace(tzinfo=utc).astimezone(jst)
としてみた。
2012-11-19
■Pythonで多次元の辞書を扱う
nodes[0][9][3]=3 nodes[0][9][4]=5
みたいな感じに使いたい*1。
今、添え字は数字にしてあるけど、実際はこの部分は辞書*2のキーの扱いにしたくて、つまりは文字列とかもつっこみたい。
検索すると、辞書のキーにはタプルが使えるので、
nodes[(0, 9, 3)]=2 nodes[(0, 9, 4)]=3
みたいに書けますよ、というのはでてくるけど、
for i in nodes[(0,9)]: print i #=>3(改行)4(改行) とでてほしい
みたいな書き方はできない。
これは今回の目的にはそぐわない。
ちょっと横道にそれるけど、実はdefaultdicみたいな書き方もしたかったりする。
print nodes[0][9][8] #=>0 とか。これをKeyErrorにしたくない
という感じ。
from pprint import pprint from collections import defaultdict nodes=defaultdict(int) nodes[0] = 5 nodes[2] = 10 pprint(nodes) #=> defaultdict(<type 'int'>, {0: 5, 2: 10}) pprint(nodes[4]) #=>0 pprint(nodes) #=> defaultdict(<type 'int'>, {0: 5, 2: 10, 4: 0})
となる。
おさらい終わり。
nodes = defaultdict(dict)
と書いてみる。
nodes[0][0]=5 nodes[0][2]=10
ok。2次元配列みたいに代入できる。
nodes[0]に初めてアクセスしたときに空の辞書がセットされるからだ。
でもこれだと、
pprint(nodes[0][4]) #occurs KeyError
うん当然。nodes[0]は普通の辞書なわけだから。
じゃあdefaultdictのデフォルト値がdefaultdictになればいいんじゃない?
nodes = defaultdict(defaultdict(int)) #occurs TypeError: first argument must be callable
defaultdict(int)がcallableじゃないっていわれる。
ふむ。
callableならいいんだね? ならばlambdaだ。
nodes = defaultdict(lambda : defaultdict(int)) nodes[0][0]=5 nodes[0][2]=10 pprint(nodes[0][4]) #=>0
いいかんじ。
次は3次元。
nodes = defaultdict(lambda : defaultdict(lambda : defaultdict(int))) nodes[0][1][0]=5 nodes[0][1][2]=10 pprint(nodes[0][1][4]) #=>0
ふむ……。なるほど。
nodes = defaultdict(lambda : defaultdict(lambda : defaultdict(int))) ^^^^^^^^^^^^^^^^^^^^^^^^^
ここの部分が、一段上のdefaultdicに与えてやった初期値に等くなる。
defaultdic.default_factoryで引っ張ってこれそう。
def multi_dimension_dict(dimension): nodes = defaultdict(int) for i in range(dimension-1): lm = nodes.default_factory nodes = defaultdict(lambda : defaultdict(lm)) return nodes
nodes = multi_dimension_dict(2) nodes[0][0]=5 nodes[0][2]=10 pprint(nodes[0]) #=>defaultdict(<type 'int'>, {0: 5, 2: 10}) pprint(nodes[0][4]) #=> 0 pprint(nodes[0]) #=>defaultdict(<type 'int'>, {0: 5, 2: 10, 4: 0})
nodes = multi_dimension_dict(3) nodes[0][9][5]=3 pprint(nodes[0][9][5]) #=> 3 pprint(nodes[0][9]) #=>defaultdict(<function <lambda> at 0x108067938>, {5: 3}) pprint(nodes[0]) #=>defaultdict(<function <lambda> at 0x103d7a938>, {9: defaultdict(<function <lambda> at 0x103d7a938>, {5: 3})})
よしよし。
nodes = multi_dimension_dict(3) nodes['aa']['bb']['cc']=4 nodes['aa']['bb']['dd']=3 pprint(nodes['aa']['bb']) #=>defaultdict(<function <lambda> at 0x109a51b18>, {'cc': 4, 'dd': 3}) sum=0 for key3rd in nodes['aa']['bb']: sum += nodes['aa']['bb'][key3rd] pprint(sum) #=>7 nodes['dd']['aa']['cc']=8 nodes['dd']['bb']['dd']=6 sum=0 for i,n in nodes.iteritems(): for j,o in n.iteritems(): for k,p in o.iteritems(): sum += nodes[i][j][k] #sum += p と等価 pprint(sum) #=>21(4+3+8+6)
まあいいんじゃないですか?
でもこれだとintしか入れられない。
def multi_dimension_dict(dimension, callable_obj=int): nodes = defaultdict(callable_obj) for i in range(dimension-1): p = nodes.copy() nodes = defaultdict(lambda : defaultdict(p.default_factory)) return nodes
にしたらいいかも!!
問題は、
nodes = multi_dimension_dict(3) nodes[0][1]=3 nodes[0][1][3]=0 #occurs TypeError
とか次元を間違えて代入しちゃうとリカバリが効かないこと。
これは解決方法が見つからないので使う時に注意するしかないかなー。
2012-11-26
■random.shuffleの話
かなり小さい len(x) であっても、 x の順列はほとんどの乱数生成器の周期よりも大きくなるので注意してください; このことは長いシーケンスに対してはほとんどの順列は生成されないことを意味します。
9.6. random - 擬似乱数を生成する - Python 2.7ja1 documentation
どういうことだろう?
例えば乱数の周期が5しかないとする。この乱数で要素5の配列をシャッフルする。
[4, 2, 3, 5, 1]
とでた。
まあシャッフルされたっぽい。
繰り返してみる。
[2, 3, 5, 1, 4]
[5, 1, 4, 2, 3]
[4, 2, 3, 5, 1]
[1, 4, 2, 3, 5]
[5, 1, 4, 2, 3]
という感じで出てきた。
順列組み合わせは5!あるはずだが、[4, 2, 3, 5, 1, 4, 2, 3, 5] の部分列5種類しか出てこない。
こういうことが起きるって話か。
ところで「かなり小さい len(x)」っていったいどのぐらいだろう?
Python は中心となる乱数生成器として Mersenne Twister を使います。これは 53 ビットの浮動小数点を生成し、周期が 2**19937-1、本体は C で実装されていて、高速でスレッドセーフです。
9.6. random - 擬似乱数を生成する - Python 2.7ja1 documentation
周期は2**19937-1だそうだ。
桁数だけ評価する
\(\log_{10}~2^{19937}~+~1=~19937~\times~\log_{10}~2~+~1\)
ですな。
import math 19937*math.log10(2)+1=6002.635023552793
まあ、6002桁ぐらい*1。
順列組み合わせが6002桁ぐらいになる配列。
math.log10(math.factorial(2081)) #=> 6003.615625445271
このへんか。
2000個程度の配列から上はrandom.shuffle()は十分にランダムではない。
実際は、もっと小さな配列からrandom.shuffle()の結果に周期性が入り込んでくるはずだ。
*1 mathモジュールは19937*math.log10(2)+1でもmath.log10(2**19937)+1でも、同じ結果を返すのだけどね。:-P