2016-04-23 5 views
2

タプルlのリストから、タプルから少なくともユークリッド距離である要素をフィルタリングする必要がありますxpython - 与えられた条件のための最小要素をフィルターにかける

  1. 私は、これはリスト内包またはラムダ関数を使用して行うことができますか?あなたはl = [(0,0), (1,1), (2,3), (3,4), (4,5)]x=(3,0)を取ることができます。

  2. ユークリッド距離が同時に最小であるlに複数の要素があるとします。それから私はからそれらの要素からランダムな要素を返す必要があります。リストの理解やラムダ関数を使ってこれを行うことはできますか?

+0

1)はい。 2)はい。それを試しましたか? –

+0

@DisplayName私はこれをどのように1行で行うのか分かりません。 3行のコードについては、そうです。 –

答えて

2

まず、Euclidian distanceを取得する関数を定義する必要があります。 1つの方法は、タプルを複素数に変換し、それらの絶対差を得ることです。

>>> dist = lambda t1, t2: abs(complex(*t1) - complex(*t2)) 

また、独自の関数を定義することもできます。最小距離を持つ値を見つけたい場合は、平方根をとる必要はありません。 この機能を組み込みのminのキー機能として使用できます。あなたはすべての最小値を取得したい場合は

>>> l = [(0,0), (1,1), (2,3), (3,4), (4,5)] 
>>> x = (3,0) 
>>> min(l, key = lambda y: dist(y, x)) 
(1, 1) 

は、あなたが変数にその値を格納し、その距離、その値に等しいすべての値を取得するには、リストの内包表記を使用することができます。

あなたがそれらのランダムな値をしたい場合は

>>> m = min(dist(y, x) for y in l) 
>>> [y for y in l if dist(x, y) == m] 
[(1, 1)] 
、使用 random.choice

>>> random.choice(_) 
(1, 1) 

ただし、この方法は二回リストを反復処理し、また、二回各値の距離を計算すること - (任意の)最小値を見つけるために1回、次に、その最小値と各値を比較するためにもう一度入力します。パフォーマンスが非常に重要な場合は、@Kasramvdの服装を使用する必要があります。ここで

+0

私はただゴルフをしようとしていました。私のデータセットが小さいので、現時点でパフォーマンスは私の懸念事項ではありません。 –

2

辞書を使用して効率的なアプローチです:

from operator import itemgetter 
from random import choice 

def find_mins(x, lst): 
    x1, y1 = x 
    result = {} 
    for x2, y2 in lst: 
     quad_dist = (x1 - x2)**2 + (y1 - y2)**2 
     result.setdefault(quad_dist, []).append((x2, y2)) 
    return choice(min(result.items(), key=itemgetter(0))[1]) 

デモ:

l = [(0,0), (1,1), (2, 2), (2,3), (3,4), (4,5)] 
x = (3,0) 

find_mins(x, l) 
(1, 1) 
find_mins(x, l) 
(2, 2) 
find_mins(x, l) 
(2, 2) 

この関数は、意図した地点からの距離に基づいて座標を分類します、その後の距離に基づいて、最小値を検索し、相対座標のリストを返すと、random.choice()を使用してランダムなポイントを取得できます。