2016-07-18 9 views
0

ich als so ein Wörterbuch haben:nächste Wertepaar in Python Liste finden

d = {'ID_1':[(10, 20), (40, 60), (125, 200)], 'ID_2': [(75, 100), (250, 300)]} 

und eine Position und ID:

pos = 70 
IDed = ID_1 
output = (40, 60) 

pos = 90 
IDed = ID_2 
expected output = (75, 100) 

pos = 39 
IDed = ID_1 
expected output = (40, 60) 

Ich möchte den Wert-Paar in der Liste finden, das ist am nächsten zum Test pos.

Ich habe dies unten versucht:

if IDed in d: 
    y = d[IDed] 
    closest = min(y, key=lambda x:abs(x-pos)) 

Das funktioniert nicht, weil sie mit einzelnen Werten keine Liste ist. Gibt es einen anderen Weg, dies mit einer ähnlichen Methode zu tun. Wenn nicht, kann ich das Problem durch eine Indexierung durch die Liste und die Berechnung der Entfernung zwischen jedem Wertepaar um ein Vielfaches herausfinden. Ich denke jedoch nicht, dass dies sehr effizient wäre.

+1

Sie ein bisschen genauer auf das, was * Nähe sein * ist. Wäre das Tupel immer noch am nächsten bei seinen Items wo '(69, 100000000)'? –

+0

@ Ev.Kounis ja, das wäre am nächsten. Ich füge weitere Beispiele hinzu – interstellar

+0

Was ist, wenn es ein Paar '(60,69)' und ein anderes '(50,90)' gibt? –

Antwort

4

Sie waren wirklich nah dran. Balg ist eine funktionierende Lösung.

d = {'ID_1': [(10, 20), (40, 60), (125, 200)], 'ID_2': [(75, 100), (250, 300)]}  
pos = 70 
IDed = 'ID_1' 

closest = min(d[IDed], key=lambda x: min(abs(y - pos) for y in x)) if IDed in d else None  
print(closest) 
# (40, 60) 

Das Problem mit Ihrem Code war, dass man x - pos mit x wobei das gesamte Tupel (z.B. (40, 60)) und pos wobei die ganze Zahl-Zielwert vorhatten.

Sie können das in einer Funktion umbrechen, um Codewiederholung zu vermeiden, falls Sie es mehrfach ausführen müssen.

def find_nearest(point_dict, id, stigma): 
    try: 
     return min(point_dict[id], key=lambda x: min(abs(w - stigma) for w in x)) 
    except: 
     return None 

d = {'ID_1': [(10, 20), (40, 60), (125, 200)], 'ID_2': [(75, 100), (250, 300)]} 
print(find_nearest(d, 'ID_1', 70)) 
# (40, 60) 

Beachten Sie, dass die Reihenfolge, in der die Begriffe in der Liste erscheinen in dem Anfang Wörterbuch verschachtelt in Fällen wie d = {'ID_1': [(10, 20), (40, 69), (71, 200)], ...} zum Beispiel wichtig ist. Begriffe 69 und 71 sind äquidistant von gegebenem Ziel 70, aber der Code gibt (40, 69) zurück, da es zuerst findet.

+0

Dies funktionierte perfekt. Vielen Dank!! Ich hatte das Gefühl, dass es einen einfacheren Weg dafür gegeben hat. – interstellar

0

Ich denke, dass Sie das Paar finden wollen, die den nächst Durchschnitt mit pos Wert hat ... Das ist also die Antwort:

d = {'ID_1':[(10, 20), (40, 60), (125, 200)], 'ID_2': [(75, 100), (250, 300)]} 
pos = 70 

closest = (0, 0) 

IDed = "ID_1" 

for i in d.items(): 
    if IDed == i[0]: 
     for x in i[1]: 
      avg = (x[0]+x[1])/2 
      avg_closest = (closest[0]+closest[1])/2 
      if abs(pos-avg) < abs(pos-avg_closest): 
       closest = x 

print closest 
+0

das ist nicht was OP will (basierend auf den ersten beiden Kommentaren) –

+0

Danke. Kein Problem... –

Verwandte Themen