重複を除外する関数と、ペアを反復処理する関数を組み合わせることができます。
最初に、リスト内の重複する後続のエントリを削除します。順序を維持し、隣り合っていない重複を許可したいので、単純なセットは使用できません。[(0, 0), (4, 4), (4, 4), (1, 1), (0, 0)]
したがって、正しい出力などの座標のリストは次のようになります[(0, 0), (4, 4), (1, 1), (0, 0)]
。これを実現する簡単な関数は次のとおりです。
def filter_duplicates(items):
"""A generator that ignores subsequent entires that are duplicates
>>> items = [0, 1, 1, 2, 3, 3, 3, 4, 1]
>>> list(filter_duplicates(items))
[0, 1, 2, 3, 4, 1]
"""
prev = None
for item in items:
if item != prev:
yield item
prev = item
yield
ステートメントは、return
実際には返されないのようなものです。呼び出されるたびに、呼び出し元の関数に値を返します。「yield」キーワードは Python で何をしますか?を参照してください。より良い説明のために。
これは単純に各アイテムを繰り返し処理し、前のアイテムと比較します。アイテムが異なる場合は、呼び出し元の関数に返され、現在の前のアイテムとして保存されます。この関数を記述する別の方法は次のとおりです。
def filter_duplicates_2(items): result = [] prev = None for item in items: if item != prev: result.append(item) prev = item return result
同じことを達成しますが、この方法ではより多くのメモリが必要になり、すべてを格納するために新しいリストを作成する必要があるため、効率が低下します。
すべてのアイテムが隣接するアイテムと異なることを確認する方法ができたので、次のペア間の距離を計算する必要があります。これを行う簡単な方法は次のとおりです。
def pairs(iterable):
"""A generate over pairs of items in iterable
>>> list(pairs([0, 8, 2, 1, 3]))
[(0, 8), (8, 2), (2, 1), (1, 3)]
"""
iterator = iter(iterable)
prev = next(iterator)
for j in iterator:
yield prev, j
prev = j
この関数は関数に似ていfilter_duplicates
ます。観察した前のアイテムを単純に追跡し、処理するアイテムごとに、そのアイテムと前のアイテムを生成します。使用する唯一のトリックは、関数呼び出しprev
を使用してリストの最初の項目に割り当てることです。next()
2 つの関数を組み合わせると、次のようになります。
for (x1, y1), (x2, y2) in pairs(filter_duplicates(coords)):
distance = getDistance(x1, y1, x2, y2)