目次へ

shelveモジュール・指南編

[TODO: 動物さん]]

できた。意外なくらい短くできた。
# -*- coding: cp932 -*-
import shelve
s=shelve.open("100poems")
 
##調べる文字のリスト
key_list = ["春", "夏", "秋", "冬", "花", "鳥", "風", "月"]
 
##結果表示のルール
##1行目:調べた文字とその文字が出現する句数
##2行目:その文字が出現する句の歌番号リスト
##3行目以降:その文字が出現する句の本文と詠み人
 
for i in key_list:
  print i , len(s[i])
  print s[i]
  for a in s[i]:
    print s['poem%03d' % (a)]

お疲れ様でした。これの実行結果は下の通りですね。

春 6
[32, 33, 2, 67, 7, 15]
山川に 風のかけたる しがらみは ながれもあへぬ もみぢなりけり (春道列樹)
久方の 光のどけき 春の日に しづ心なく 花の散るらむ (紀友則)
春過ぎて 夏来にけらし 白妙の 衣ほすてふ 天の香具山 (持統天皇)
春の夜の 夢ばかりなる 手枕に かひなくたたむ 名こそをしけれ (周防内侍)
天の原 ふりさけみれば 春日なる 三笠の山に いでし月かも (阿倍仲麻呂)
君がため 春の野に出でて 若菜つむ わが衣手に 雪はふりつつ (光孝天皇)
夏 3
[2, 36, 98]
春過ぎて 夏来にけらし 白妙の 衣ほすてふ 天の香具山 (持統天皇)
夏の夜は まだ宵ながら あけぬるを 雲のいづこに 月やどるらむ (清原深養父)
風そよぐ ならの小川の 夕ぐれは みそぎぞ夏の しるしなりける (従二位家隆)
秋 12
[1, 37, 70, 71, 75, 47, 22, 23, 87, 79, 94, 5]
秋の田の かりほの庵の 苫をあらみ 我が衣手は 露にぬれつつ (天智天皇)
白露に 風の吹きしく 秋の野は つらぬきとめぬ 玉ぞ散りける (文屋朝康)
さびしさに 宿を立ち出でて ながむれば いづくもおなじ 秋の夕ぐれ (良選法師)
夕されば 門田の稲葉 おとづれて 蘆のまろやに 秋風ぞ吹く (大納言経信)
ちぎりおきし させもが露を いのちにて あはれ今年の 秋もいぬめり (藤原基俊)
八重むぐら しげれる宿の さびしきに 人こそ見えね 秋は来にけり (恵慶法師)
吹くからに 秋の草木の しをるれば むべ山風を 嵐といふらむ (文屋康秀)
月みれば ちぢにものこそ かなしけれ わが身一つの 秋にはあらねど (大江千里)
村雨の 露もまだひぬ まきの葉に 霧たちのぼる 秋の夕ぐれ (寂蓮法師)
秋風に たなびく雲の たえ間より もれいづる月の 影のさやけさ (左京大夫顕輔)
み吉野の 山の秋風 さ夜ふけて ふるさと寒く 衣うつなり (参議雅経)
奥山に もみぢふみわけ なく鹿の 声聞く時ぞ 秋はかなしき (猿丸太夫)
(以下略)

こんな調子で順に結果が表示され、「春」は6コ、「夏」は3コ、「秋」は12コ… で、一番多いのは秋の12コと出ました。いいですね。筆者も答えを忘れましたが、きっと正解です!

お寄せしてくださったスクリプトを見てまいりましょう。

最初に key_list に、調べたい単漢字をぜんぶ入れたリストを作って入れておく。あとでこれは for ループで使っています。

検索結果がどう表示されるのかをコメントとして人間用に書き添えてくださいました。まず1行目に出るのが、キーそのものと、キーで辞書(shelve)を調べたときに出てくるモノの len。つまりこの漢字を含む歌の総数ですね。で、2行目に表示するのは、歌番号リストをそのままリストとして表示。これは目でチェックに使うためによいですね。そして最後に、そのリストの値を for で順番に使いつつ、'poem001' とかいった文字としてキーを作れるように文字列をフォーマットしながら辞書(shelve)を調べて、その値(つまり歌)を全部表示しました。

よく書いてくださいました。ばっちりです。頼もしいことです。

ひとつだけ、チェック。文字列フォーマットを作るときに、'poem%03d' % (a) という表現をしてくれました。ここは、'poem%03d' % a とだけしてくれてもよいですよ。穴埋め部分が二つ以上あるときは、(a, b, c) とかいった感じで値の部分をカッコ+コンマで書くんですが、ひとつだけのときは裸のまま値を置いていいのです。まあ、些細なところです。

べつのかた

もう一人回答をくださいました。

できた。
# coding: cp932
import shelve
 
s = shelve.open('100poems')
siraberu_kanji = ["春", "夏", "秋", "冬", "花", "鳥", "風", "月"]
max_f=0
max_c="無"
for c in siraberu_kanji:
    konoji = s[c]
    print "\n" + "【" + c + "】"
    n = 0
    for a in konoji:
        print s['poem'+'0'*(3-len(str(a)))+str(a)]
        n = n+1
        if n > max_f:
            max_f = n
            max_c = c
    print "---> 全" + str(n) + "首"
print "\n結論:頻度が最も多いのは「"+ max_c + "」で、全" + str(max_f) + "首でした。"

これの実行結果はこんなふう。

【春】
山川に 風のかけたる しがらみは ながれもあへぬ もみぢなりけり (春道列樹)
久方の 光のどけき 春の日に しづ心なく 花の散るらむ (紀友則)
春過ぎて 夏来にけらし 白妙の 衣ほすてふ 天の香具山 (持統天皇)
春の夜の 夢ばかりなる 手枕に かひなくたたむ 名こそをしけれ (周防内侍)
天の原 ふりさけみれば 春日なる 三笠の山に いでし月かも (阿倍仲麻呂)
君がため 春の野に出でて 若菜つむ わが衣手に 雪はふりつつ (光孝天皇)
---> 全6首

【夏】
春過ぎて 夏来にけらし 白妙の 衣ほすてふ 天の香具山 (持統天皇)
夏の夜は まだ宵ながら あけぬるを 雲のいづこに 月やどるらむ (清原深養父)
風そよぐ ならの小川の 夕ぐれは みそぎぞ夏の しるしなりける (従二位家隆)
---> 全3首

【秋】
秋の田の かりほの庵の 苫をあらみ 我が衣手は 露にぬれつつ (天智天皇)
白露に 風の吹きしく 秋の野は つらぬきとめぬ 玉ぞ散りける (文屋朝康)
さびしさに 宿を立ち出でて ながむれば いづくもおなじ 秋の夕ぐれ (良選法師)
...

(途中略)

結論:頻度が最も多いのは「秋」で、全12首でした。

こいつも実行結果はばっちりです。前の方と、実現のための戦略はほぼ同じです。ただしこちらは表示を美しく整えてくれています。で、最大数がなんだったかを実行結果の最終行でレポートまでしてくれるというこの配慮。やるなー。

siraberu_kanji という変数は、今から調べようとする漢字のリストを表現するための変数名。そして、konoji はその一文字づつが含まれる歌のリストを取っておくための変数名。一見ファニーな感じではありますが、あとでソースコードが読みやすいということを意識するなら、決しておかしなものではありません。人が読みやすいスクリプトを書こうとされる点に感心します。

いささか驚いたのは、1から100の数字を 'poem001' とかいう文字列に直す処理。 'poem'+'0'*(3-len(str(a)))+str(a) とな… えーと、1から9だったら、'00' にくっつけて、11から99だったら '0' にくっつけて… と頭の中で実験してみましたが、これできっとあっていますね。確かに正しく歌を呼び出すためのキーを作ることができます。い、いろんな方法があるものだなあ。

というわけで、たいへん結構です! お答えを寄せてくださる皆様、毎度ありがとう。

 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki