HPO機密日誌

自己をならふといふは、自己をわするるなり。

奇跡ではない生還 : Pythonの再帰コール

結局、昨日のCheckIOの課題を解くのに日付変更線を越えてしまった。が、あえて4月1日付けでエントリーを起こしておく。

いくつかの問題が解けなかったが、ほとんどそりゃダンプリストだろうというくらい変数をPrintで出力して、CheckIOでは窓が小さすぎるのでエディターにコピーして追いかけていって解決できた。

教訓がいくつかある。自分のための備忘メモ。五十も近いにわかプログラマーはすぐに問題点を忘れてしまう。

  • 基本中の基本だが、Pythonでは、リストの代入を行っても、ポインターを渡すだけなので、「子」の関数の中でローカルに操作するリストが欲しい場合は、list_new = [x in list_old]とかやらないとだめ。setからsetで渡すのも、set_new=set([x in set_old])とする。
  • 「枝」をすべて検討するためなどに、再帰の呼び込みをする場合は、関数の最初にぬける条件分岐をする。さっさとreturnなり、yieldなりして、枝を吐き出させて「答え」をリストにして、その中から最適なものを選ぶなりした方がいい。というか、そうしないと「帰れない!」「抜け出せない!」という状態にはまる。
  • ローカルのスコープでグローバルであったほしい変数に代入を行っただけで、おかしくなる。「噛まれる」と表現している方がいたが、まさにget in toubleだ。他の方のreviewをさせていただいて、グローバル変数をローカルで扱う時はappendとかaddとかでやっていた。
  • これはできてない反省でいうのだが、変数のスコープがあいまいであり、classの定義が柔軟なPython特性を生かすのなら、下手に関数を定義するより、classで定義して、関連する変数一式を渡してしまう方が、上記のいくつかの問題とのからみからいってもエレガントだと想う。class定義をさけるために、再帰コールする関数はほとんどの変数を渡す書き方をした。反省!

CheckIO Teleport

Disposable teleports :: CheckiO

にしても、あまりにも私にとってCheckIOは時間消費が激しい。それでも、プログラムを書けるようになっていっているという手応えは感じる。

解けた課題でもclassを使って書き直すなど再チャレンジできるところがPythonのまたよいところかもしれない。