何かを書き留める何か

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

『Effective Python』Item 9: 大きなリスト内包表記ではジェネレータ式を検討しよう

『Effective Python』の続き。みんな大好きリスト内包表記第三弾。

Effective Python: 59 Specific Ways to Write Better Python (Effective Software Development Series)

Effective Python: 59 Specific Ways to Write Better Python (Effective Software Development Series)

www.effectivepython.com

リスト内包表記は新たなリストを生成してしまうから巨大な入力に対してはジェネレータ式を使おうぜ、という話。至極正しい。 面白いなと思ったのは、次のコード。

import random
with open('/tmp/my_file.txt', 'w') as f:
    for _ in range(10):
        f.write('a' * random.randint(0, 100))
        f.write('\n')

it = (len(x) for x in open('/tmp/my_file.txt'))
roots = ((x, x**0.5) for x in it)
print(next(roots))

ジェネレータ式にジェネレータ式が!というもの。 next(roots)とするとちゃんと内部的にnext(it)も行われる。

ただ、イテレータにはステートフルなので気をつけろ、という話もある。 それは「Item 17: 引数によるイテレーションは防御的に行う」で1項目かけて説明している。 これに関しては筆者がサンプルを公開している。 Effective Python › Item 17: Be Defensive When Iterating Over Arguments

このサンプルを翻訳して公開しよう、という企みから単なる自己満足と化したこの一連の投稿、果たしていつまで続くのか。

『Effective Python』Item 10: rangeよりもenumerateを使おう

『Effective Python』の続き。

Effective Python: 59 Specific Ways to Write Better Python (Effective Software Development Series)

Effective Python: 59 Specific Ways to Write Better Python (Effective Software Development Series)

www.effectivepython.com

今回はタイトル以上の情報は何も無い…が

flavor_list = ['vanilla', 'chocolate', 'pecan', 'strawberry']
for i in range(len(flavor_list)):
    flavor = flavor_list[i]
    print('%d: %s' % (i + 1, flavor))

のようなコードを書かずに

flavor_list = ['vanilla', 'chocolate', 'pecan', 'strawberry']
for i, flavor in enumerate(flavor_list, 1):
    print('%d: %s' % (i, flavor))

こう書きましょう、というのはまさにPythonicな書き方だなあと思う。