質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

Python:ループの回し方がわかりません

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 434

Ykkykk

score 95

ループの回し方がよくわかりません。

lst = [1, 5, 2, 32, 3, 41, 0, 5, 26, 7, 18, 9, 10]
lst2 = [1 ,-2 ,-3 ,1 ,3 ,4 ,5 ,-6, -7, 8, 9]
a = 0
len_lst = len(lst) - 1

print("forの前のa", a)
for i in lst:
    c = lst2[a] +lst2[a+1]
    d = lst2[a] + i
    print(c, d)
    while a < len_lst:
        while lst2[a] * d < 0:
            a += 1
            print("最後のa", a)


以上のようなコードを書いたのですが、出力としては、

forの前のa 0
6, 2


と表示されたあと処理が動かなくなり、Ctrl+Cで処理を中断しました。

^CTraceback (most recent call last):
  File "loop.py", line 11, in <module>
    while lst2[a] * d < 0:
KeyboardInterrupt


エラーメッセージとしては以上の文言が表示されます。
処理としては、インクリメントする変数aを用意し、lst2[a] * d < 0であればaを増やして計算を行い、そうでない場合はaをインクリメントせずに計算を行うということがしたいです。

上記のコードだと、インクリメントしたあとにうまくfor文に戻れていないような気がしています。
どのようにすればfor文に戻って計算することができるのでしょうか?

 修正と追記

lst = [1, 5, 2, 32, 3, 41, 0, 5, 26, 7, 18, 9, 10]
lst2 = [1 ,-2 ,-3 ,1 ,3 ,4 ,5 ,-6, -7, 8, 9]
a = 0
len_lst = len(lst) - 1

print("forの前のa", a)
for i in lst:
    c = lst2[a] +lst2[a+1]
    d = lst2[a] + i
    print("for", a)
    while a < len_lst:
        while lst2[a] * d < 0:
            a += 1
            print("while", a)
        else:
            a += 1
            print("else", a)


以上のようにelseを置くと無限ループを回避することはできているのですが、出力としては、

len 10
forの前 0
for 0
2
else 1
while 2
while 3
else 4
else 5
else 6
else 7
while 8
while 9
else 10
Traceback (most recent call last):
  File "loop.py", line 9, in <module>
    c = i + lst2[a] + lst2[a+1]
IndexError: list index out of range


となっています。これだとfor文の中ではインクリメントされたaが使われていないということだと思うのですが、インクリメントされたaをfor文の中でも使用したいと思っています。

追記

上記のコードでも、for文の中でインクリメントされたaの値が使用されているということをお教えいただきました。
aがある値の間for文の中の計算を行い、そのたびごとに条件を評価し、条件から外れた場合にはaをインクリメントして再びfor文の計算に戻る、という繰り返しを行いたいのですが、そのためにはwhile文を使わないということでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Meganezaru

    2018/10/26 11:04

    for文のiがどこにも利用されていないので、やりたい計算の全貌が理解できないかも。二つのリストから、どのような計算をしたいのかがわかると回答しやすいかもしれません。

    キャンセル

  • mather

    2018/10/26 11:42

    先程見ていた質問内容からコードが変更されていますね。質問したいことに対してまちがった情報を載せていた場合は書き換える必要があると思うのですが、回答を受けてコードを書き換えた場合などは元のコードを書き換えずに追記することをおすすめします。

    キャンセル

  • Ykkykk

    2018/10/26 11:50

    ご忠告いただきありがとうございます。不慣れなもので大変失礼いたしました。本当に申し訳ありませんでした。

    キャンセル

回答 1

checkベストアンサー

+2

while a < len_lst:
    while lst2[a] * c < 0:
        a += 1
        print("最後のa", a)


この部分で、aが1、len_lstが10、lst2[a]が-2、cが-1とします。
そのとき、while a < len_lstは条件が真なのでループに入りますが、
次のwhile lst2[a] * c < 0-2 * (-1) < 0が偽となるのでこのループには入りません。

すると、再び値が変わらぬままwhile a < len_lstに入り、条件が真となりループされ、
次のwhile lst2[a] * c < 0-2 * (-1) < 0が偽となるのでこのループには入りません。

というのが繰り返されているので無限ループとなっています。
何がしたいコードかわからないので、whileをどこに置くかは指摘できませんが、
少なくともwhile lst2[a] * c < 0のループに入らなかったときの対応を
正しく行うことで無限ループにはならなくなるかと思います。


いつの間にか質問文が追記されてたので回答も追記。

これだとfor文の中ではインクリメントされたaが使われていないということだと思うのですが、

いえ、for文の中でもきちんとwhile文でインクリメントされた値が使われています。
ただし、IndexErrorとあるように、aの値が進みすぎているので、
リストの範囲外の要素にアクセスしてしまっている状態です。

while a < len_lst:
    while lst2[a] * d < 0:
        a += 1
        print("while", a)
    else:
        a += 1
        print("else", a)


for文の1回のループにつき、while a < len_lstのループ内で、
aはlen_lstと同値になるまでループします。
for文の2回目のループに入るときにはalen_lstの値と同じになり、
lst2lstよりも要素数が少ないので、IndexErrorとなります。


さらに回答追加されてたので追記

正直質問者様がどういう処理をしたいのかが伝わっていません。

aがある値の間for文の中の計算を行い

  • 「aがある値の間」とはどの値なのか
  • 「for文の中の計算」とは何の計算なのか

そのたびごとに条件を評価し

  • 「for文の中でaがある間」繰り返すなら、2重ループになり、その中に条件分岐が来るはずです。

条件から外れた場合にはaをインクリメント

  • 現状のコードでは条件が外れる外れないに関わらずインクリメントしてます。

再びfor文の計算に戻る

現状ではwhile文に戻るので、for文に戻るのであればwhile文を抜ける処理が必要です。

while文を使わないということでしょうか?

使い方によります。
まずはどんな処理をしたいのかを明確にし、それに従ってループするのか条件分岐だけなのかを
判断して適切なプログラムを組む必要があります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/26 11:49

    elseを置いてそこでもインクリメントするようにしたところ、一つ目のwhile文の直前でaをプリントすると一回だけ0が表示され、そのあとにelseの中のプリント文が表示されるようになってしまいました。while文の外側ではaがインクリメントされていないように思いますが、いずれにせよ書き方によっては可能ということなのですね。
    ありがとうございます。

    キャンセル

  • 2018/10/26 12:55

    再度ご回答いただきありがとうございます。
    この状態でfor文の中でもインクリメントされた値が使用されているのですね。
    aがある値の間、for文の中でlstから値を取り出し計算を行い、whileの条件から外れた場合にaをインクリメントし再びfor文の中の処理を行うというような動きを想定していたのですが、forが一回回る度ごとにaが限界までインクリメントされているのですね。

    キャンセル

  • 2018/10/26 15:28

    何度もご回答に追記いただき本当にありがとうございます。
    どのような処理を行いたいのかというのはあるのですが、うまく別のコードに置き換えることができませんでした。申し訳ありません。
    ご回答いただいた点を参考に検討していきたいと思います。
    お手数おかけしてしまい、申し訳ありません。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る