Python3.10 から標準ライブラリに採用された関数ですが、
itertools.pairwise が目的の動作をします。
3.9 以前は標準ライブラリには含まれず、サンプルコードがドキュメントのレシピに記載されてました。
3.9 以前の環境では、レシピに載っている関数は、標準ライブラリには含まれませんが、
pip install more-itertools
で別途インストールできます。
python
1
2# 3.10
3from itertools import pairwise
4
5# 3.9 以前 more-itertools
6from more_itertools import pairwise
7
8# 代替実装 (簡易版)
9# 一つ前の値をprevに記録しておき、
10# 新しい値currentと同時に返すジェネレーターとして実装。
11def pairwise(sequence):
12 iterable = iter(sequence)
13 prev = next(iterable)
14 for current in iterable:
15 yield prev, current
16 prev = current
17
18# pairwise() の挙動確認
19
20for n, m in pairwise([1, 2, 3, 4]):
21 print(n, m)
22
23# 1 2
24# 2 3
25# 3 4
緯度・経度が別々のリストなのであれば、
組込関数のzip関数で組み合わせられます。
python
1# zip関数の挙動確認
2
3for a, b in zip([1, 2, 3], [4, 5, 6]):
4 print(a, b)
5
6# 1 4
7# 2 5
8# 3 6
効率を考えないのであれば、zip() を使い、
こんな実装方法も可能です。
python
1
2def pairwise(seq):
3 return zip(seq[:-1], seq[1:])
4
5# seq = [1, 2, 3, 4] とした場合、
6# seq[1:] は [2, 3, 4]
7# seq[:-1] は [1, 2, 3] なので
8# zip([1, 2, 3], [2, 3, 4]) => [(1,2), (2,3), (3, 4)]
9
10# 要素数が一致しない場合は、残りの要素を無視するので、
11# 最初のスライスは省略可 zip(seq, seq[1:])
追記: GeoPy にも ユーティリティとして pairwise 関数がありました。
python
1# https://github.com/geopy/geopy/blob/ade9c1b68c83a1fc76d90bc0ff603f6b34dfbbbf/geopy/util.py
2# from geopy.util import pairwise でインポートできるはず
3
4def pairwise(seq):
5 """
6 Pair an iterable, e.g., (1, 2, 3, 4) -> ((1, 2), (2, 3), (3, 4))
7 """
8 for i in range(0, len(seq) - 1):
9 yield (seq[i], seq[i + 1])
最初に紹介した方法との違いは、リスト等のシーケンスのみを対象とします。
itertoolsの実装では、より汎用的で、イテレーターを対象にすることが出来ます。
python
1
2lat_list = [35.1, 35.2, 35.3]
3lng_list = [140.0, 139.9, 139.8]
4
5for prev, current in pairwise(zip(lat_list, lng_list)):
6 print(prev, current)
7
8# (35.1, 140.0) (35.2, 139.9)
9# (35.2, 139.9) (35.3, 139.8)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/21 16:27