Python - 文法 - ループ

 クラウディア
1. 概要
2. ループしながら配列の項目を削除
3. 多重ループをぬける

1. 概要

 わたしの気になっているとこだけね。  本ページは、下記のサイトを参考にさせていただきました。
[小ネタ]Pythonのループ内でリストの要素を削除する時の注意点 | Developers.IO

2. ループしながら配列の項目を削除

 これは、配列のオブジェクトを扱うときに、いつも問題になることなのですが・・・。  配列の全件ループを行っているときに、配列自体を操作しようとすると、そのループが正常に回っていくかという命題です。
import pprint

pp = pprint.PrettyPrinter()

list = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

pp.pprint(list)

for i in list:
    if (not (i % 3)):
        list.remove(i)

pp.pprint(list)

for i in list:
    list.remove(i)

pp.pprint(list)


 を実行すると
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 4, 5, 7, 8, 10]
[2, 5, 8]
 てなことになる。  1 から 10 までの値の入っている配列で、9~11 で、3の倍数を削除してますが、なんかうまくいったように見えます。  しかし、調子にのって全件削除しちゃおうと 15~16行を実行すると、1つ飛ばしで残ってしまう。  ループ中に、中身が削除されたために、カウンタがずれちゃって削除した次のカウントの処理を飛ばしちゃうんですな。  3の倍数だと、飛ばした次は、3の倍数ではないので、気が付かないということになります。  これを解決するには、
import pprint

pp = pprint.PrettyPrinter()

list = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

pp.pprint(list)

for i in list[:]:
    if (not (i % 3)):
        list.remove(i)

pp.pprint(list)

for i in list[:]:
    list.remove(i)

pp.pprint(list)



 というような書き方をするとよいそうです。  「配列[:]」で、オブジェクトのコピーを使うそうです。  これを辞書型でやろうとすると書き方がわからない。  今んとこ、全部のキーを削除してやろうと思うと、わたしには、下記のような書き方しかできません。
import pprint

pp = pprint.PrettyPrinter()

dic = {
          1 :  1,
          2 :  2,
          3 :  3,
          4 :  4,
          5 :  5,
          6 :  6,
          7 :  7,
          8 :  8,
          9 :  9,
         10 : 10,
    }

pp.pprint(dic)

for i in list(dic):
    del dic[i]

pp.pprint(dic)



3. 多重ループをぬける

 本項は、「Pythonで多重ループ(ネストしたforループ)からbreak | note.nkmk.me」を参考にさせていただきました。  多重ループを抜けるには、他の言語では、フラグを使って外のループで判定したり、メソッドや関数を作って、一気にリターンしたりしますが。  「Python」では、「break」「else:」「continue」を組み合わせると一気に抜けられるようです。  「for 文」内で、「else」中のがなじめないですが、なかなか便利。  ただし、わたしは、くっきりは理解できていない(2020年6月10日)。
for i in range(1, 5):
    print("外側のループ", i)

    for j in range(6, 10):
        print("内側のループ", i, j)

        if (j == 8):
            break
    else:
        continue
    break


 というソースを書いて実行すると、下記の結果が得られます。
外側のループ 1
内側のループ 1 6
内側のループ 1 7
内側のループ 1 8
 うすらぼんやりとは、理解できます。  三重になると、頭がこんがらがってくる。
for i in range(1, 5):
    print("外側のループ", i)

    for j in range(6, 10):
        print("内側のループ", i, j)

        for k in range(11, 15):
            print("内側のループ", i, j, k)

            if (k == 13):
                break
        else:
            continue
        break
    else:
        continue
    break


 というソースを書いて実行すると、下記の結果が得られます。
外側のループ 1
内側のループ 1 6
内側のループ 1 6 11
内側のループ 1 6 12
内側のループ 1 6 13
 各ネストに「break」「else:」「continue」が必要らしい。
高速大容量レンタルサーバ10GJETBOY
 
 
カウンタバックグラウンド