- ベストアンサー
PythonのNodeクラスのtraverse関数の解説
- PythonのNodeクラスのtraverse関数は、指定された値までのパスを見つけるための再帰関数です。
- この関数は、与えられた値が自身のデータと一致するかどうかを確認し、一致する場合は空のリストを返します。
- 一致しない場合は、子ノードを再帰的にトラバースし、子ノードのデータをリストに加えた結果を返します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
では、C++との比較で書きましょう。 C++では、インスタンスには自分自身を指すポインタ this が勝手に定義されます。 Pythonでは、thisに該当するものは作られません。メソッドでは、自分自身の参照を受け取ります。 > で、色々考えてみたのですが、selfは実際にはthisとは結構違い、 > child.traverse(leaf)という呼び出しは、無理にC++っぽく書いてみると、 > ↓の感じになるという感じではないかと想像したのですがあってますでしょうか? > this->traverse( child , leaf ); 少し違います。C++でむりやりやるなら、こんな感じでしょうか clas Node{ static LIST traverse( Node * self, Node * leaf) { self->~ ; ... } }; Node * child ; Node * leaf ; Node::traverse(child, leaf); // child->traverse(leaf) ではない 難しかったら、 「インスタンスメッソドの定義では、第1引数は自分自身を受け取るためのもの」 「インスタンスメッソド呼び出し時の引数は、defの第2引数以降に対応」 と覚えておけばいいかと。 ちなみに、selfというのは慣例で、別の名前を使っても構いません。無理に変える必要もありませんが。
その他の回答 (1)
- rinkun
- ベストアンサー率44% (706/1571)
詳しいというほど詳しくないですが・・・。 肝はyieldです。「Python yield」で検索すれば理解できるだけの情報は集まると思います。 関数の中でyieldを使うと普通の関数ではなくなりジェネレータになります。 traverseを呼び出すと実行はせずに単にジェネレータを返します。 実際の実行はジェネレータのnext()を呼び出したときに行われ、yieldまで実行すると中断して 結果を返します。次にそのジェネレータのnext()を呼び出すと先ほどの続きを実行して次のyield で結果を返します。traverseの最後まで実行すると例外StopIterationを起こします。 使う方ではジェネレータを取得してnext()を繰り返し呼び出すのですが、forループのinの後に置けば 自動的に実行できるので簡単ですね。 traverseの場合はdataがleafであるようなNodeをNodeを辿りながら探す動作になると思います。 C++で同様の動作を書くのは結構手間なので勘弁してください。
お礼
ご回答いただきありがとうございます。 yieldについてのご提示で疑問の半ばまで解消した感じでした。 本当に助かりました。 ありがとうございます!
補足
はじめまして、ありがとうございます! 本当に、本当に助かります(>_<) yieldについてはご提示の通り検索してみたところ、 細かいところはともかく、Pythonでよく使われる機能であることがわかりました。 遅延評価は不要なので、C++での動作の代替はlist等を用いれば大丈夫そうな感じでした。 で、もう一つわからないことがあるのです。 ↓のような呼び出しがあります。 child.traverse(leaf) しかし、関数の定義的には↓の感じです。 def traverse(self, leaf): selfは検索したところ、Python特有のもので、C++でいうthisに近いとか…。 で、色々考えてみたのですが、selfは実際にはthisとは結構違い、 child.traverse(leaf)という呼び出しは、無理にC++っぽく書いてみると、 ↓の感じになるという感じではないかと想像したのですがあってますでしょうか? this->traverse( child , leaf ); 悩んでいるのは、traverseを再帰で呼び出した時、 関数の1行目で以下の処理を行なっていることです。 if self.data == leaf: selfをthisに置き換えると、子を辿らずに自身を参照し続けてしまいます。 selfをthisではなく、呼び出したインスタンスと考えれば、ちゃんと子を辿って終息するのがわかります。 本当にすみません、とりあえずPythonの実行環境を入れて試してみようと思いますが、 もし、教えていただけたら幸せです。 よろしくお願いします!!
お礼
私一個勘違いしてました。 child->traverse( lead )で呼び出せば、 1行目のif self.data == leaf:部分をC++で if( this->data == lead )と記述しても多分、正しく動作しますね。 selfについてのご提示で疑問がスッキリ解消しました! Pythonの文法は初めて読んだ私でもなんとなく想像がつくくらい自明で素敵ですが、 selfやyield、その他いろいろ、ちゃんと勉強しないとわからないところがありそうでした。 ありがとうございました!