以下のコードで引数とローカル変数の関係について教えてください。
ゼロから作るDeep leaningからの抜粋です。
def predict(self, x): for layer in self.layers.values(): x = layer.forward(x) return x
上記のコードでは、引数 とローカル変数が同じxになっています。
これは以下のどちらになるでしょうか。
1.xは引数を参照するものであり、xには引数で受け取った配列データの上にlayer.forward(x)の値が上書きされる。
2.xはローカル変数であり、引数xとは関係ない。したがってyに宣言して、return yにしても同じ結果になる。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答4件
1
1でも2でもないです。
そもそも、関数の仮引数として書かれた名前はローカルな名前空間に束縛されるので、定義上ローカル変数です。以下を参照ください。
https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding
以下の構造で、名前が束縛されます: 関数の仮引数 (formal parameter) 指定
ある名前がブロック内で束縛されているなら、 nonlocal や global として宣言されていない限り、それはそのブロックのローカル変数 (local variable) です。
だからxは仮引数でかつローカル変数です。
例えばですが、
python
1def twice_and_increment(x): 2 x = x * 2 3 x = x + 1 4 return x
と
python
1def twice_and_increment(x): 2 d = x * 2 3 i = d + 1 4 return i
を比較するのがよいかもしれません。(2倍して1を足して返す関数ですが、処理自体は本筋とは関係ないです)
上は、どうせそれ以降で使わないんだから違う名前にする意味ないよね派で
下は、もう使わないとしても違う名前を付けるべき派のコードです。
どっちでもいいでしょう。
関数の中身がある程度より大きいなら下の方が好ましく、小さいなら上でもぜんぜん構わない、といった程度の印象です。
投稿2022/01/21 06:52
総合スコア10623
1
ベストアンサー
self.layers
が
python
1self.layers = OrderedDict() 2self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) 3self.layers['Relu1'] = Relu() 4self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
であったときに、predict
は
python
1x = self.layers['Affine1'].forward(x) 2x = self.layers['Relu1'].forward(x) 3x = self.layers['Affine2'].forward(x) 4return x
という意味になる。
~.predict(x1)
と呼んだときに
forward
でx
の状態を変更するメソッドが呼ばれていない限り
x1
に影響は及ぼさない。
わかりにくいなら
python
1def predict(self, x): 2 ret = x 3 for layer in self.layers.values(): 4 ret = layer.forward(ret) 5 return ret
と書いてもいいと思う。
実験コード
いろいろなパターンで試してみるといいでしょう。
python
1def forward(x,i): 2 # x.append(i) 3 # return x 4 return x+[i] 5 6def hoge(x): 7 for i in range(10): 8 ret = forward(x,i) 9 return ret 10 11 # for i in range(10): 12 # x = forward(x,i) 13 # return x 14 15 # ret = x 16 # for i in range(10): 17 # ret = forward(ret,i) 18 # return ret 19 20x1 = [5] 21x2 = hoge(x1) 22 23print(x1) 24print(x2) 25
投稿2022/01/21 05:32
編集2022/01/21 05:35総合スコア13376
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
0
ありがとうございます。
投稿2022/01/27 13:24
総合スコア56
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
0
1ですね。
xは仮引数であり、実行時は実引数に束縛されます。
この関数では、実引数はlayer.forward(x) に渡されて返り値が、改めてxに束縛されて、return x で返されます。
仮引数は初期値として実引数の値に束縛されえちるだけで、ローカル変数と同じものです。 ので、再束縛(再代入)も可能です。
1つの関数/プログラムの中で変数を複数の意味で利用するのはあまりマナーがよくないですね。
あと、ループの意味もよくわからない。
python
1def predict(self, x): 2 for layer in self.layers.values(): 3 ret = layer.forward(x) 4 return ret
たとえばこんな風に別の変数にしたほうがわかりやすい。
投稿2022/01/21 04:35
編集2022/01/21 04:39総合スコア11449
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
関連した質問
Q&A
解決済
NotionAPIでページコンテンツを取得したい
回答1
クリップ1
更新
2023/05/31
Q&A
解決済
複数条件で絞り込む検索ボタンを作成したい
回答2
クリップ0
更新
2023/06/06
Q&A
解決済
ハンバーガーメニューの挙動について(transitionが、もとに戻る時には適応されない)
回答2
クリップ0
更新
2023/06/02
Q&A
解決済
自作した確率密度による確率分布に従うランダムなデータをn件生成するには?
回答1
クリップ0
更新
2023/06/06
Q&A
受付中
[GAS] 日本語・全角・特定の記号のみを許容するスクリプトを作成したい
回答1
クリップ1
更新
2023/06/06
Q&A
解決済
javaのResultSet.get~が端数処理する
回答1
クリップ0
更新
2023/06/06
意見交換
受付中
Wordpressのphpファイルにデータベースの接続情報を直接記入しても大丈夫なのでしょうか。
回答39
クリップ3
更新
2023/05/25
意見交換
受付中
二次元配列の中身の後ろに空白を入れるけど末尾だけは空白をつけずに改行を出力する問題
回答18
クリップ1
更新
2023/05/26
同じタグがついた質問を見る
Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。