問題

次のコードで示されるリスト変数my_listについて、値が偶数である要素を削除するために、del文を使った方法として最も適切なものはどれですか?

変数my_listには次のようなリストが格納されている。

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

プログラム1:

for i in range(len(my_list)): 
    if my_list[i] % 2 == 0: 
        del my_list[i]

プログラム2:

for i in range(len(my_list) - 1, -1, -1): 
    if my_list[i] % 2 == 0: 
        del my_list[i]

プログラム3:

for i, val in enumerate(my_list): 
    if val % 2 == 0:
        del my_list[i+1]

プログラム4:

for i, val in enumerate(my_list[::-1]): 
    if val % 2 == 0: 
        del my_list[i]

 

選択肢

(a) プログラム1

(b) プログラム2

(c) プログラム3

(d) プログラム4

  • a
  • b
  • c
  • d

Python del文に関する知識問題

答え

(b)

解説

正解はプログラム2です。コードを実際に実行した場合の出力を見てみましょう。

for i in range(len(my_list) - 1, -1, -1): 
    print(i, my_list)
    if my_list[i] % 2 == 0: 
        del my_list[i]
8 [1, 2, 3, 4, 5, 6, 7, 8, 9]
7 [1, 2, 3, 4, 5, 6, 7, 8, 9]
6 [1, 2, 3, 4, 5, 6, 7, 9]
5 [1, 2, 3, 4, 5, 6, 7, 9]
4 [1, 2, 3, 4, 5, 7, 9]
3 [1, 2, 3, 4, 5, 7, 9]
2 [1, 2, 3, 5, 7, 9]
1 [1, 2, 3, 5, 7, 9]
0 [1, 3, 5, 7, 9]

for文で回すイテラブルオブジェクトのrange(len(my_list) - 1, -1, -1)についてですが、ここではmy_listの要素を逆順に取得するためにのインデックスを生成しています。リストを昇順(0から)ではなくて降順から(8から)回すことで、del文によってリストが更新された後も影響を受けずに更新(削除)を続けることができます。

【その他の選択肢】

プログラム1:
昇順からリストを更新しているため、正しいインデックスで要素を削除できなくなる可能性があります。実際にコードを実行すると、次のようになります。

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

print('len(my_list): {}'.format(list(range(len(my_list)))))

for i in range(len(my_list)): 
    print('i={}, my_list={}'.format(i, my_list))
    if my_list[i] % 2 == 0: 
        del my_list[i]
len(my_list): [0, 1, 2, 3, 4, 5, 6, 7, 8]
i=0, my_list=[1, 2, 3, 4, 5, 6, 7, 8, 9]
i=1, my_list=[1, 2, 3, 4, 5, 6, 7, 8, 9]
i=2, my_list=[1, 3, 4, 5, 6, 7, 8, 9]
i=3, my_list=[1, 3, 5, 6, 7, 8, 9]
i=4, my_list=[1, 3, 5, 7, 8, 9]
i=5, my_list=[1, 3, 5, 7, 9]

Traceback (most recent call last):
  File "Main.py", line 10, in <module>
    if my_list[i] % 2 == 0: 
IndexError: list index out of range

この結果からもわかるように昇順でリストの要素を削除しようとすると、削除した際にリストの長さが短くなってしまうので、インデックスがリスト長を超えてしまうことからIndexErrorが発生することがあります。

プログラム3:
i番目の要素が偶数のときに、i+1番目の要素を削除しています。したがって、偶数ではなく奇数を削除する処理内容になっていることから誤りです。

プログラム4:
my_list[::-1]はリストを逆順にする処理で、my_listに格納されている[1, 2, 3, 4, 5, 6, 7, 8, 9][9, 8, 7, 6, 5, 4, 3, 2, 1]にします。逆順にしたリストをemunerate()を使ってforループで回していますが、for内のインデックスを示すiとdel文で削除する要素の順番が対応していないため、誤りです。

またmy_listに格納されているリストについては昇順で削除しているため、IndexErrorが発生します。

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

print(my_list[::-1])

for i, val in enumerate(my_list[::-1]): 
    print(i, my_list)
    if val % 2 == 0: 
        del my_list[i]
[9, 8, 7, 6, 5, 4, 3, 2, 1]
0 [1, 2, 3, 4, 5, 6, 7, 8, 9]
1 [1, 2, 3, 4, 5, 6, 7, 8, 9]
2 [1, 3, 4, 5, 6, 7, 8, 9]
3 [1, 3, 4, 5, 6, 7, 8, 9]
4 [1, 3, 4, 6, 7, 8, 9]
5 [1, 3, 4, 6, 7, 8, 9]
6 [1, 3, 4, 6, 7, 9]
7 [1, 3, 4, 6, 7, 9]

Traceback (most recent call last):
  File "Main.py", line 11, in <module>
    del my_list[i]
IndexError: list assignment index out of range

 

 

 

テスト一覧

スキルテストが提供しているテストの一覧です。ぜひ学習や実力チェックに役立ててください。