Python 3 エンジニア認定基礎試験の公式テキストとして、オライリーのPythonチュートリアル第4版が指定されています。
しかしチュートリアルとはいいつつも完全な初心者が読むにはやや不親切な場所が目立ちます。
特にそっくりそのまま写しても実行できないコードが何の注意書きもなく書かれているのは初心者泣かせです。
なので、私NMRが(自信はありませんが)加筆することで最低限動くコードとしてみようかなと思います。
私自身Python初日かつ、経験は浅いので修正箇所を見つけた場合はなるべくわかりやすく教えていただけると助かります。
また、熟練者から見ると「その言葉遣いは誤解を招く」などあると思います。
そういった表現の訂正も歓迎です。
第4章 4-2 P24のfor文
このコードで筆者が言いたいことの意訳。
Pythonを書いている時に「コレクション(リストやセットのこと)に要素を追加、削除したい」ということがあると思います。
例えば100人の顧客リスト「UserListA」の女性だけを削除して、男性だけの「UserListB」を作りたいなどです。
直感的に考えると、UserListAをfor文で直接操作して要素を削除したくなります。
しかしそうするとPythonはエラーを返します。
なぜならPythonでfor文を回すときにはイテレーターという物が内部で動作しています。
イテレーターが動作している時に、内部の要素の数を変えてはいけないからです。
※イテレーターに関するこの説明は正確ではありません。
(私NMRの知識・理解不足です。)
戦略 コピーをかけるのパターン
# usersは辞書オブジェクトです。
# key:valueの形で値を保存します。
users = {1: 'active', 2: 'inactive'}
# ここでusersをコピーしています。copy()もitems()もPythonで使えるメソッドです。
# メソッドというのはprint()とかです。
# {}内の1: 'active', 2: 'inactive'
# をuser, statusに代入して、最後の要素になるまで繰り返します。
# もしkey:valueは1組なのでif文でstatus(value)の中身が'inactive'
# だった場合のみ、該当するuser(key)を削除するというコードです。
for user, status in users.copy().items():
if status == 'inactive':
del users[user]
# 出力内容の確認のため
print(users)
# 出力結果
{1: 'active'}
戦略 新しいコレクションを作るのパターン
users = {1: 'active', 2: 'inactive'}
active_users = {}
for user, status in users.items():
if status == 'active':
active_users[user] = status
print(active_users)
# 出力結果
{1: 'active'}
参考までにPythonチュートリアルの筆者的に直感的でないパターン
users = {1: 'active', 2: 'inactive'}
for user, status in users.items():
if status == 'inactive':
del users[user]
print(users)
↑これはイテレーターでエラーになります。
Pythonチュートリアルの筆者はこういったエラーに直面した場合は、先に挙げた2つのコードのように対処してくれたらいいよ!と言ってくれているわけです。