基本的な質問にて失礼します。
以下のfor文ですが、1回目のループでnに入ったtaroが出力され、同様に2回めのループではjiro、3回めではsaburo、4回目ではshiroが出力されるのは直感的に、なにも違和感がありません。
python
1for n in ['taro','jiro','saburo','shiro']: 2 print(n) 3 4taro 5jiro 6saburo 7shiro
しかし、たとえば、以下のようにHelloが4回出力されるケースについて、素直になれないのです。たしかに、inのリストの数が4つ、なのでhelloも4つなのですが..もう少し、突っ込んだ因果関係を知りたいと思ったりしています。どうぞ、よろしくお願いいたします。
for n in ['taro','jiro','saburo','shiro']: print('Hello') hello hello hello hello
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/19 01:56
2020/07/19 23:42
2020/07/20 01:02
2020/07/20 01:33
2020/07/20 01:38
2020/07/20 01:45
2020/07/20 01:50
2020/07/20 07:17 編集
回答8件
0
理屈ではなくイメージとして想像しやすい様に
シンプルですがこれではいかがですか?
理解できる部分と、理解し難い部分の中間を取ったコードだと思いますが。。。
python
1for n in ['taro','jiro','saburo','shiro']: 2 print('hello' + n) 3 4>> hello taro 5>> hello jiro 6>> hello saburo 7>> hello shiro
for文では、何も必ず取り出した要素(n)を使用しなければならないというルールはありません。
従ってhelloのみが出力されます。
python
1for n in ['taro','jiro','saburo','shiro']: 2 print('hello') 3 4>> hello 5>> hello 6>> hello 7>> hello
投稿2020/07/16 04:01
総合スコア1438
0
太郎さん、次郎さん、三郎さん、四郎さんが列に並んでいて、
「一人ずつ前に進んで紙にお名前をお書きください」とお願いしたら紙には
太郎 次郎 三郎 四郎
と残るでしょうが
「お名前はけっこうですので前に進んで一人ずつ紙に✓を書き入れてください」とお願いしたら紙には
✓✓✓✓
と残りますよね。
(追記)
現実で「お名前はけっこうですので前に進んで一人ずつ紙に✓を書き入れてください」って言われたら「誰が並んでいたかは気にしてなくて、人数だけ知りたいんだな」って思いますよね。
それと同じでfor文でイテラブルから取り出した値が代入されている変数nがあって、でも「for文の本体でその変数を使っていない」と判明したら「どんな値がイテラブルから取り出されたかは気にしてなくて、個数だけが必要なんだな」とプログラマは思うわけです。
よいプログラマは
python
1for unused in ['taro','jiro','saburo','shiro']: 2 print('Hello')
として名前に意図を込めるとか、
python
1for _n in ['taro','jiro','saburo','shiro']: 2 print('Hello')
として命名規則で意図を込めるとか(値を使わない変数は_
で始めるという慣習はPython界隈では通用します)、
python
1for n in ['taro','jiro','saburo','shiro']: 2 # 中身に関係なく個数分出力する 3 print('Hello')
としてコメントにwhyを残すとかします。
投稿2020/07/15 08:43
編集2020/07/15 09:13総合スコア11235
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/15 22:55
2020/07/16 02:19
2020/07/19 00:43
2020/07/19 01:05
2020/07/19 01:40
2020/07/19 01:57
2020/07/19 02:03
0
仕組み
仕組みについては残念ながらあなたの直感はどうでもいい話です。
事実は動かしようがないので、直感と事実が違うならあなたの直感の方を事実に寄せてください。
for..in...
がどういうモノなのかはy_shinodaさんの回答にもありますこちらを参照します。
8. 複合文 (compound statement) — Python 3.8.4 ドキュメント
これをものすごく簡単に要約すると
python
1for n in ['taro','jiro','saburo','shiro']: 2 何か
は
python
1n = 'taro' 2何か 3n = 'jiro' 4何か 5n = 'saburo' 6何か 7n = 'shiro' 8何か
と同じです。(break
やcontinue
とかあったら話は別ですが。)
「何か」(suite)の部分で、列挙したもの:n
(target_list)を無視してはならないとはどこにも書いてませんし、
実際無視してもエラーにはならないので、質問文のn
を使わないコードは合法です。
そう言語仕様が定まった理由
「なぜ列挙したものを無視してもいい言語仕様になっているか」についてはpythonを作った人に聞くしか無いので正確には言えませんが、
無視できなければ例えば「リストxsの個数だけ'hello'と表示する」という
「リストの中身はどうでもいいけど個数分だけ繰り返したい」場合にfor...in...
で書けなくなって困るな、ということはわかります。
他の言語を見てみると、変数を置いておきながら使わないと、「使ってないけど大丈夫?」と気を遣って警告を出してくれる言語はいくつかあります。
例えばswiftは「使わないならそうと分かるように変数名を_
にしろ」と警告を出してきます。
swift
1for i in 0..<10 { 2 print("hello") 3}
main.swift:2:5: warning: immutable value 'i' was never used; consider replacing with '_' or removing it for i in 0..<10 { ^ _
投稿2020/07/20 02:30
総合スコア13553
0
投稿2020/07/15 08:37
退会済みユーザー
総合スコア0
0
元の回答
for 文
のふるまいについて、こちらのドキュメントを参照すると良いかもしれません:
8. 複合文 (compound statement) — Python 3.8.4 ドキュメント
python
1for_stmt ::= "for" target_list "in" expression_list ":" suite 2 ["else" ":" suite]
expression_list の結果対するイテレータが生成されます。
その後、イテレータが与えるそれぞれの要素に対して、
イテレータから返された順に一度づつ、スイートが実行されます。
...
その後、スイートが実行されます。
全ての要素を使い切ったとき
(シーケンスが空であったり、イテレータが StopIteration 例外を送出したときは、即座に)、
else 節があればそれが実行され、ループは終了します。
リンク先の説明で分かりにくい表現がいくつかりますので補足します
イテラブルオブジェクト
くり返し可能なオブジェクトのことで、
list
, dict
などが該当します
用語集 — Python 3.8.4 ドキュメント
イテレーター
実際にくり返しを行うためのオブジェクトです
用語集 — Python 3.8.4 ドキュメント
組み込み型 — Python 3.8.4 ドキュメント
スイート
これは上記の for 文
の構造の説明の中の suite
の部分を示しています
ドキュメントが日本語訳されたときに
カタカナに変換されてしまっているため、わかりにくくなっています
追記
イテラブルオブジェクトには、要素を反復して取り出せるイテレータが付与されている。
この解釈は、合っていますでしょうか。
「要素を反復して取り出せるイテレータ」
この部分は正しいです
「イテラブルオブジェクトには、イテレータが付与されている」
付与されているとは限りません
イテラブルオブジェクトとイテレーターの関係については
次の記述が参考になるでしょう
iterable
(list, str, tuple といった) 全てのシーケンス型や、 dict や ファイルオブジェクト といった幾つかの非シーケンス型、 あるいは Sequence 意味論を実装した iter() メソッドか getitem() メソッドを持つ任意のクラス
また、
組み込み関数 iter() の引数として渡すと、 オブジェクトに対するイテレータを返します
投稿2020/07/15 08:22
編集2020/07/16 02:57総合スコア3272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
もう少し、突っ込んだ因果関係を知りたいと思ったりしています。
何がわからないのでしょうか。ループに入ったn
は、無視しても構いません。
投稿2020/07/15 08:12
総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/15 08:12
2020/07/15 08:17
2020/07/15 08:22 編集
2020/07/15 08:23
2020/07/15 08:41 編集
2020/07/15 08:54
0
この場合の関係は、「リストの要素の個数分、繰り返し実行される」というだけですね。
繰り返される処理にn
の値が使われないことに違和感があるのでしょうが、実世界でも、
「並んでいる人数分、握手して微笑む」みたいな繰り返し処理をすることがありますね。
この場合、相手が誰かは関係なく、並んでいる人数分、動作を繰り返すだけです。
投稿2020/07/15 08:37
総合スコア11990
0
見える化しました
for index, value in enumerate(['taro','jiro','saburo','shiro']): print('index:{}, value:{},'.format(index, value) + ' Hello')
投稿2020/07/15 08:14
総合スコア6426
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/15 08:27
2020/07/15 08:30
2020/07/15 08:35
2020/07/15 08:52
2020/07/15 12:39
2020/07/15 12:39
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。