1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PEP 618 (Add Optional Length-Checking To zip) を読んだよメモ

Posted at

先日、PEP 618 (Add Optional Length-Checking To zip)Accept されたというコミットを見かけました。
そこで、今回は PEP 618 を読んでみようと思います。

概要

  • zip() 関数を使うとき、暗黙的に各要素の長さが同じであることを期待していることがある (ことが多い)

  • 長さの異なる要素を誤って与えてしまうと、意図せずデータを欠損してしまうことになる

    >>> list(zip([1,2,3], [4]))  # 2, 3 は失われてしまう
    [(1, 4)]
    
  • 次のような関数があるときに、リストを渡すと意図通りに動くが、イテレータを渡すとうまく動かない (イテレータが先に進んでしまうので)。

    def apply_calculations(items):
        transformed = transform(items)
        for i, t in zip(items, transformed):
            yield calculate(i, t)
    
  • zip() にオプションを追加し、各要素が同じ長さであることをチェックする

アプローチ

Python 3.10 に zip() 関数に strict というパラメータが追加されました。
strict に正の値を指定した場合、各要素の長さが等しくないときに ValueError が発生します。

>>> for item in zip([1, 2, 3], [4], strict=True):
...     print(item)
...
(1, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: zip() argument 2 is shorter than argument 1

zip() の第2引数が第1引数より短い、というエラーが出ています。
ちなみに、長さが一致しないというのを検知するまでループが回っている点には注意が必要です。

なお、デフォルトではいままでの挙動のままのままです(strict=False 相当、つまり長さが異なる場合はデータを捨てる)。

>>> for item in zip([1, 2, 3], [4]):
...     print(item)
...
(1, 4)
>>>

感想

  • 言われてみるとうっかりミスでデータ欠損を起こしそうな予感があるので、これは嬉しい
  • でも、明示的に strict=True と指定しないといけないので、指定しわすれてトラブルになりそう
  • イテレータの例はやらかしそうな気がした (すぐに気づくとは思うけど…)
  • 3.10 が楽しみですね
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?