何かを書き留める何か

数学や読んだ本について書く何かです。最近は社会人として生き残りの術を学ぶ日々です。

『Effective Python』Item 11: 複数のイテレータを同時に処理するならzipを使おう

『Effective Python』の続き。そろそろAmazonのリンクは目障りなので外す。アフェリエイトなどやっていないのでね…。 www.effectivepython.com

互いに関連している複数のリストを処理する際に、

names = ['Cecilia', 'Lise', 'Marie']
letters = [len(n) for n in names]
longest_name = None
max_letters = 0

for i in range(len(names)):
    count = letters[i]
    if count > max_letters:
        longest_name = names[i]
        max_letters = count

print(longest_name)

というコードを書かずにzipですっきり書こうぜ、という話。 zipの注意点はイテレータの長さが違うと最も短いイテレータで切り詰めてしまうこと。

公式ドキュメント2. 組み込み関数 — Python 3.4.2 ドキュメントから引用すると、

zip() は、等しくない長さの入力に対しては、長い方のイテラブルの、終端の対にならない値を気にしないのでなければ、使うべきではありません。そのような値が重要なら、かわりに itertools.zip_longest() を使ってください。

のように、itertools.zip_longest()を使えばよい。

『Effective Python』Item 12: forやwhileループ後のelseブロックは避ける

『Effective Python』の続き。for/elsewhile/elseダメ絶対 www.effectivepython.com

Python 言語リファレンス — Python 3.4.2 ドキュメントを読むと、for文やwhile文の後にelse節を追加できることが書いてある。 筆者は、いかにこのelseが直感的ではないかを3段落に渡って書いている。if/elsetry/except/else/finalyと比べて意味合いが違うとか、初心者は混乱するなど。

私はこれまで気にしていなかったが、次のコードを見てちょっと使うのをやめようと感じた。 さて、以下のコードはどのような動作をするでしょう?

for x in []:
    print('For block!')
else:
    print('For Else block!')
while False:
    print('While block!')
else:
    print('While Else block!')

一応、筆者はfor/elsewhile/elseの使いどころを説明するものの、代替案を提示して「forやwhileループ後のelseブロックは避けろ」とした。 きっと、嫌な思い出があるのだろうなあ…。