何かを書き留める何か

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

『Effective Python』Item 5: シーケンスのスライス方法を知ろう

『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

sequenceはシークエンスと書くものだと思っていたが、用語集にはシーケンスとあったのでタイトルもシーケンスにした。 シーケンスとは用語集によると

整数インデクスによる効率的な要素アクセスを__getitem__()特殊メソッドを通じてサポートし、長さを返すlen()メソッドを定義したiterableです。

iterableってなんだ、となると

要素を一つずつ返せるオブジェクトです。

となる。dict__getitem__()特殊メソッドを通じてサポートし、長さを返すlen()メソッドを定義したiterableであるが整数インデクスではなくmappingであることに注意しよう…とは書いてない。このあたりは知っているものとして話が進んでいる(前書きを読んでいない)。

Item 5はシーケンスのスライスの振る舞いについての話で、start <= i < endとなるのは今更驚くことではない。 Rubyだとsomelist[2..4]somelist[2...4]で前者はstart <= i <= endで後者はstart <= i < endとなる。 Rubyの場合、使い分けが出来るのは何かと便利であるがぱっと見わからない。 個人的には1種類しかないPythonの方が好きである。

スライスでハマリやすいのは参照渡しと値渡しのような状況が起きる点だと思っている。 例えば、

a = [1, 2, 3, 4, 5]
b = a[:]
c = a
a[:2] = [99, 100]
print(a)
print(b)
print(c)

ようなコードがあった場合、それぞれの出力結果はどうなるであろうか。

[99, 100, 3, 4, 5]
[1, 2, 3, 4, 5]
[99, 100, 3, 4, 5]

おわかりいただけだろうか。 b = a[:]の場合はコピーを、c = aの場合はaが示している参照を渡している。 この違いは気づきにくいが、特に注意喚起することなくこうですよ、という書き方だった。

もしかして、このようなミスをするのは私だけだろうか。