2011-04-14 5 views
0

Supposons que coffre est une liste de coordonnées qui sont deux listes d'éléments.Retourne le résultat le plus grand ou le plus petit d'une boucle for en python

Par exemple poitrine = [[2,4], [4,5], [1,3]]

Avec la fonction ci-dessous, je veux la distance entre le point (x, y) et chaque des points de la poitrine. Donc, comme il est, la fonction reviendrait ces trois distances, non? Mais ma question est, comment puis-je retourner seulement le plus petit (ou plus grand) résultat de ces trois valeurs? Y at-il un moyen de le faire sans créer une nouvelle liste de distances?

def makeMove (planche, poitrine, x, y):

for cx, cy in chests: 
    distance = sqrt(abs((x-cx)**2) + abs((y-cy)**2))) 
    return distance 
+0

Ne devriez-vous pas utiliser 'abs (x - cx)' au lieu de 'abs (x) - abs (cx)' (et respectivement pour y)? Ce dernier est garanti pour donner une valeur non négative alors que la dernière est incorrecte pour les valeurs négatives et se bloque si la différence est <0. Aussi, tapotement stylistique: Utilisez des tuples pour des séquences immuables de longueur fixe comme des points et ne placez pas d'espaces autour de la fonction invocation parens (comme dans le second appel 'abs'). – delnan

Répondre

7

Vous pouvez utiliser max() ou min() plus une expression du générateur ...

return max(
    sqrt(abs(x - cx) + abs(y - cy)) 
    for cx, cy in chests) 

Notez également que l'optimisation, vous pouvez préférer faire cela à la place (puisque si sqrt(x) > sqrt(y), puis x > y) pour réduire le nombre d'appels sqrt:

return sqrt(max(
    abs(x - cx) + abs(y - cy) 
    for cx, cy in chests)) 

(Etes-vous sûr de ne pas vouloir équarrir les distances au lieu de abs() en les utilisant? La formule de distance normale est sqrt((x-x')^2 + (y-y')^2) ...)

1

En l'état, votre fonction renvoie uniquement la première distance. Lorsque l'instruction return est rencontrée lors de la première itération de la boucle, la fonction renvoie, et c'est tout.

En outre, votre formule pour la distance est probablement erronée, puisque l'argument de sqrt() peut être négatif. Dans le code ci-dessous, je suppose que vous voulez la distance euclidienne à la place.

Bien que vous puissiez obtenir le minimum et le maximum en utilisant des expressions de générateur, cela nécessiterait de calculer deux fois toutes les distances. Construire sur la boucle que vous avez écrit, vous pourriez faire

def distance_squared(p0, p1): 
    return sum((x0 - x1) ** 2 for x0, x1 in zip(p0, p1)) 

def makeMove(board, chest, x, y): 
    chest_iter = iter(chest) 
    min_dist = distance_squared(next(chest_iter), (x, y)) 
    max_dist = min_dist 
    for c in chest_iter: 
     dist2 = distance_squared(c, (x, y)) 
     min_dist = min(min_dist, dist2) 
     max_dist = max(max_dist, dist2) 
    return sqrt(min_dist), sqrt(max_dist) 
0
max_distance = max([sqrt((abs(x) - abs (cx)) + (abs(y) - abs(cy))) for cx, cy in chests]) 
min_distance = min([sqrt((abs(x) - abs (cx)) + (abs(y) - abs(cy))) for cx, cy in chests]) 

Fondamentalement, vous tournez la boucle dans une compréhension de la liste, (de sorte que vous créez en fait une nouvelle liste), et appelez max et min pour obtenir le les plus petits membres de la nouvelle liste de distances.

+3

Aucune raison d'utiliser une compréhension de liste quand une expression de générateur suffirait. – Amber

Questions connexes