Ich habe dieses Problem, bei dem ich die Liste der Zahlen in jeder Liste für die Koordinaten X und Y erhalten muss und herausfinden muss, welche der Koordinaten der ersten Koordinate der Liste am nächsten liegt. Dafür habe ich den folgenden Code:

import math

list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

if len(list2) == len(list1):
    print ("number of elements does match\n")
else:
    print ("number of elements doesnt match\n")

a=1
dist_list = []

for i in range(1, len(list1)):
    x1 = list1[0]
    y1 = list2[0]

    x2 = list1[a]
    y2 = list2[a]

    dist = abs(math.sqrt((x1-(x2)**2) - (y1-(y2)**2)))
    a=a+1
    dist_list.append(dist)

print ("distancias:", dist_list, "\n")

for element in iterable:
        if element:
            return
    return False

print(list1[b],",",list2[b], "es la coordenada mas cercana")
#                            "is the closest coordinate"

In diesem Fall zeigen die Abstände zwischen den Koordinaten, dass diese Koordinate 1,3 1,4 am nächsten kommt.

distancias: [6.48074069840786, 5.656854249492381, 2.23606797749979]

Ich muss das hier sagen: print(list1[b],",",list2[b], "es la coordenada mas cercana")

Ich habe die Funktion any() gesucht und gefunden und laut Python-Dokumentation kann ich die Formel wie folgt neu erstellen:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

Aber ich kann nicht sehen, wie ich es neu erstellen kann, um das gewünschte Ergebnis zu erzielen. Außerdem muss ich sagen, dass ich für diese Übung nur for, in, while, sqer, abs und append verwenden kann.

1
René Martínez 24 Feb. 2020 im 02:16

5 Antworten

Beste Antwort

any() ist dafür nutzlos. Sie müssen min() neu erstellen (oder besser numpy.argmin())

Sie müssen zu Beginn den ersten Abstand ermitteln und mit allen anderen Werten vergleichen. Wenn der andere Wert kleiner ist, müssen Sie den Wert und seinen Index beibehalten.

b = 0   # get first index
b_value = dist_list[0]   # get first value

# compare with other distances
for i in range(1, len(dist_list)):
    if dist_list[i] < b_value:  # if new distance is smaller
        b = i  # keep new index
        b_value = dist_list[i]   # keep new value

b = b+1  # because `dist_list[0]` has value for `list1[1]`, not `list1[0]`

(Übrigens: Normalerweise würde ich enumerate() anstelle von range(len()) verwenden, aber ich gehe davon aus, dass Sie es nicht wissen.)


BEARBEITEN: Wie @Tomerikoo hervorhob, ist die Formel für die Entfernung falsch. Es sollte sein:

dist = math.sqrt((x1-x2)**2 + (y1-y2)**2)

Vollständiger Code

import math

list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

if len(list2) == len(list1):
    print ("number of elements does match\n")
else:
    print ("number of elements doesnt match\n")

dist_list = []

x1 = list1[0]
y1 = list2[0]

for i in range(1, len(list1)):

    x2 = list1[i]
    y2 = list2[i]

    #dist = abs(math.sqrt((x1-(x2)**2) - (y1-(y2)**2)))
    dist = math.sqrt((x1-x2)**2 + (y1-y2)**2)

    dist_list.append(dist)

print ("distancias:", dist_list, "\n")

b = 0
b_value = dist_list[0]

for i in range(1, len(dist_list)):
    if dist_list[i] < b_value:
        b = i
        b_value = dist_list[i]

b = b+1  # because `dist_list[0]` has value for `list1[1]`, not `list1[0]`

print(list1[b],",",list2[b], "es la coordenada mas cercana")
#                            "is the closest coordinate"
4
furas 24 Feb. 2020 im 00:02

Sie müssen nicht die Quadratwurzel machen, um Entfernungen zu vergleichen, sondern nur die Summe der Delta-Quadrate. Die min-Funktion kann mit ihrem Schlüsselparameter verwendet werden, um das kleinste Element in einer Liste (oder einem Iterator) basierend auf einem berechneten Wert abzurufen. Mit zip können Sie die beiden Listen zu Koordinatenpaaren kombinieren, die benutzerfreundlicher sind. Zip ist ein Iterator, der mit der min-Funktion kompatibel ist:

list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

points = zip(list1,list2)  # combine lists into (x,y) points
bx,by  = next(points)      # get the base point

# comparative distance calculation (square root not needed)
def distance(point): px,py = point; return (px-bx)**2+(py-by)**2

# minimum of remaining points based on distance calculation
px,py = min(points,key=distance)

print((px,py),"is nearest to",(bx,by))

# (1, 3) is nearest to (1, 4)

Wenn Sie nach einer Lösung ohne Verwendung von min oder zip suchen, finden Sie hier eine einfache Schleife, die auf Iteratoren basiert und das gewünschte Ergebnis liefert. Mit den Iteratoren können Sie beide Listen gleichzeitig durchlaufen, ohne Indizes zu verwenden (die Indizierung wird in Python als hässlich angesehen).

ix,iy    = iter(list1),iter(list2) # list iterators
bx,by    = next(ix),next(iy)       # base point
cx,cy,cd = None,None,None          # closest point and distance
for px in ix:
    py  = next(iy)                # progress through iterators
    dxy = (px-bx)**2+(py-by)**2   # compute comparative distance
    if cd is None or dxy < cd:
        cx,cy,cd = px,py,dxy      # keep first or closest found

print((px,py),"is nearest to",(bx,by))
0
Alain T. 24 Feb. 2020 im 02:52

Erstellen Sie eine Variable, die für die nächste Entfernung steht

import math

list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

if len(list2) == len(list1):
    print ("number of elements does match\n")
else:
    print ("number of elements doesnt match\n")

dist_list = []
x1 = list1[0]
y1 = list2[0]
closest = 10000
closest_xy = 0
for i in range(1, len(list1)):
    x2 = list1[i]
    y2 = list2[i]
    dist = math.sqrt((x1-x2)**2 + (y1-y2)**2)
    if closest > dist:
        closest = dist
        closest_xy = i
    dist_list.append(dist)

print ("distancias:", dist_list, "\n")


print(list1[closest_xy],",",list2[closest_xy], "es la coordenada mas cercana")
#                            "is the closest coordinate"
0
steak_Overcooked 24 Feb. 2020 im 00:06

Das Mathematikmodul verfügt über eine hypot() Funktion, die würde es relativ einfach machen, das zu tun, was Sie brauchen:

import math


def find_closest(list1, list2):
    if len(list2) != len(list1):
        raise RuntimeError("number of elements does match")
    if len(list1) < 2:
        raise RuntimeError("the lists must contain at least two points")

    x0, y0 = list1[0], list2[0]
    index = 1
    min_dist = math.hypot(x0-list1[1], y0-list2[1]) # Distance between first and second pt.
    # See if any of the remaining pts are closer.
    for i in range(2, len(list1)):
        dist = math.hypot(x0-list1[i], y0-list2[i])
        if dist < min_dist:
            min_dist = dist
            index = i

    return (list1[i], list2[i])  # Closest point.


list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

print(find_closest(list1, list2), "es la coordenada mas cercana")

Ausgabe:

(1, 3) es la coordenada mas cercana

Wenn Sie math.hypot() nicht verwenden können, ist es ziemlich einfach, eine eigene basierend auf math.sqrt() zu schreiben:

def hypot(dx, dy):
    return math.sqrt(dx*dx + dy*dy)
1
martineau 24 Feb. 2020 im 00:09

Nur zum Spaß:

Dies kann leicht mit einer Kombination aus min erfolgen und zip:

import math

list1 = [1, 2, 1, 1]
list2 = [4, 7, 6, 3]

ref_point = (list1[0], list2[0])
points = zip(list1[1:], list2[1:])

x,y = min(points, key=lambda point: (point[0]-ref_point[0])**2 + (point[1]-ref_point[1])**2)

print(x, ",", y, "es la coordenada mas cercana")

Beachten Sie, dass abs nicht wirklich notwendig ist, da Zahlen hoch 2 immer positiv sind und weil wir nur vergleichen möchten, ist sqrt auch nicht notwendig (wenn sqrt(x) > sqrt(y) dann auch { {X3}}).

2
Tomerikoo 28 Feb. 2020 im 08:31