web-dev-qa-db-fra.com

Python: pour chaque élément de la liste, appliquez une fonction sur la liste.

[1,2,3,4,5], comment puis-je faire quelque chose comme 

1/1, 1/2, 1/3,1/4,1/5, ...., 3/1,3/2,3/3,3/4,3/5,.... 5/1,5/2,5/3,5/4,5/5

Je voudrais stocker tous les résultats, trouver le minimum et renvoyer les deux nombres utilisés pour trouver le minimum. Donc, dans le cas que j'ai décrit ci-dessus, j'aimerais renvoyer (1,5).

Donc, fondamentalement, je voudrais faire quelque chose comme

pour chaque élément i dans la listemap une fonction sur tous les éléments de la liste, en prenant i et j comme paramètresstorez le résultat dans une liste principale, recherchez la valeur minimale dans la liste principale et renvoie les arguments i, jutilisé pour calculer cette valeur minimale.

Dans mon vrai problème, j'ai une liste d'objets/coordonnées, et la fonction que j'utilise prend deux coordonnées et calcule la distance euclidienne. J'essaie de trouver une distance euclidienne minimale entre deux points quelconques, mais je n'ai pas besoin d'un algorithme sophistiqué.

25
joe calimar

Vous pouvez le faire en utilisant list comprehensions et min () (code Python 3.0):

>>> nums = [1,2,3,4,5]
>>> [(x,y) for x in nums for y in nums]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)]
>>> min(_, key=lambda pair: pair[0]/pair[1])
(1, 5)

Notez que pour exécuter ceci sur Python 2.5, vous devez transformer l'un des arguments en float ou faire from __future__ import division pour que 1/5 soit correctement égal à 0,2 au lieu de 0.

42
Kiv

Si j'ai raison de penser que vous voulez trouver la valeur minimale d'une fonction pour toutes les paires possibles de 2 éléments d'une liste.

l = [1,2,3,4,5]

def f(i,j):
   return i+j 

# Prints min value of f(i,j) along with i and j
print min( (f(i,j),i,j) for i in l for j in l)
10
Triptych

Un peu de python lisible:

def JoeCalimar(l):
    masterList = []
    for i in l:
        for j in l:
            masterList.append(1.*i/j)
    pos = masterList.index(min(masterList))
    a = pos/len(masterList)
    b = pos%len(masterList)
    return (l[a],l[b])

Faites-moi savoir si quelque chose n'est pas clair.

3
Andrea Ambu

Si vous importez le paquet numpy, il contient de nombreuses fonctionnalités pratiques. Il sera probablement beaucoup plus efficace d'utiliser leurs structures de données que des listes de listes, etc.

from __future__ import division

import numpy

data = numpy.asarray([1,2,3,4,5])
dists = data.reshape((1,5)) / data.reshape((5,1))

print dists

which = dists.argmin()
(r,c) = (which // 5, which % 5) # assumes C ordering

# pick whichever is most appropriate for you...
minval = dists[r,c]
minval = dists.min()
minval = dists.ravel()[which]
3
Mr Fooz

En le faisant de façon mathématique ...

nums = [1, 2, 3, 4, 5]
min_combo = (min(nums), max(nums))

À moins, bien sûr, que vous ayez des négatifs. Dans ce cas, cela ne fonctionnera pas car vous voulez réellement les valeurs absolues minimale et maximale - le numérateur doit être proche de zéro et le dénominateur éloigné de celui-ci, dans un sens ou dans l'autre. Et les doubles négatifs le casseraient.

2
Nikhil Chelliah

Si vous travaillez avec Python ≥2.6 (y compris 3.x), vous pouvez:

from __future__ import division
import operator, itertools

def getmin(alist):
    return min(
        (operator.div(*pair), pair)
        for pair in itertools.product(alist, repeat=2)
    )[1]

getmin([1, 2, 3, 4, 5])

EDIT: Maintenant que j'y pense et que je me souviens bien de mes mathématiques, cela devrait également donner la réponse en supposant que tous les nombres sont non négatifs:

def getmin(alist):
    return min(alist), max(alist)
1
tzot
>>> nums = [1, 2, 3, 4, 5]    
>>> min(map((lambda t: ((float(t[0])/t[1]), t)), ((x, y) for x in nums for y in nums)))[1]
(1, 5)
0
Chandrakant Silver