Trouver l'indice de la valeur min ou max en Python
J'ai une structure de la forme:
>>> items
[([[0, 1], [2, 20]], 'zz', ''), ([[1, 3], [5, 29], [50, 500]], 'a', 'b')]
Le premier élément de chaque n-uplet est une liste de plages, et je veux faire un générateur qui me donne les plages dans l'ordre croissant basé sur l'indice de départ.
Depuis la plage-les listes sont déjà triés en fonction de leur indice de départ de cette opération est simple: c'est juste un classement de fusion. Je suis l'espoir de le faire avec une bonne efficacité de calcul, donc je pense qu'une bonne façon de faire implicitement le suivi de l'état de mon fusion est tout simplement de la pop le front de la liste de tuple qui a le plus petit indice de départ dans sa gamme de la liste.
Je peux utiliser min()
pour obtenir [0, 1]
qui est le premier que je veux, mais comment puis-je obtenir l'index de celui-ci?
J'ai ceci:
[ min (items[i][0]) for i in range(len(items)) ]
qui me donne le premier élément de chaque liste, que je peux ensuite min()
au cours d'une certaine façon, mais il échoue une fois que la liste est vide, et aussi il n'est pas clair comment faire pour obtenir l'index à utiliser pop()
avec sans regarder en arrière dans la liste.
Pour résumer: vous Souhaitez construire générateur qui renvoie pour moi:
([0,1], 'zz', '')
([1,3], 'a', 'b')
([2,20], 'zz', '')
([5,29], 'a', 'b')
([50,500], 'a', 'b')
Ou même de manière plus efficace, j'ai seulement besoin de ces données:
[0, 1, 0, 1, 1]
(les indices des tuples, je veux profiter de l'avant de l'élément de l')
- J'ai écrit un
mergeiter
fonction pour une réponse précédente; j'ajoute des indices avecenumerate()
. - Étant assez vert avec Python, j'ai eu quelques difficultés grokking que
mergeiter
fonction de la vôtre au premier abord. Mais, après avoir examiné ces autres réponses, de toute évidence, c'est le bon type d'approche. Et pourtant c'est la seule qui n'est pas affiché comme une réponse...
Vous devez vous connecter pour publier un commentaire.
Cela fonctionne:
Donne:
En détail. Le générateur:
Donc, la seule chose nécessaire est de tri et d'obtenir seul le choix de l'indice:
min
à tous les indices. Prendre la plus petite et la répétition jusqu'à ce que la liste est consommé? Je lance un test quelques qui a indiqué que le tri est plus rapide pour les grandes listes et si les articles sont déjà dans un certain ordre.min
tenter d'index dans les vides des listes. Probablement une amélioration de l'ordre de O(n log n) par rapport à la mienne qui est en O(n^2). Pourrait être améliorée en évitant l'utilisation deenumerate
.Retour de l'indice du plus grand élément dans
items
et l'élément lui-même.max(enumerate(items), key=lambda x: x[1])
, pour vous sauver d'une importation.Cette méthode trouve l'index de l'élément maximum de tout objet iterable et ne nécessite aucune externes importations:
max(enumerate(l), key=lambda t: list(reversed(t)))
. Contrairement à l'original, quand max s'affiche plusieurs fois, ce serait vous donner le dernier indice (qui est le plus utile dans quelques cas)De l'index max d'une liste:
Si il y a doublon max valeurs lst, ce sera le retour de l'indice de la première valeur maximale trouvée.
Encore une autre façon d'obtenir le argmax est:
c'est donc un réel moyen rapide et facile pour obtenir cette version efficace vous êtes à la recherche pour:
Ici en est-il de vos articles pour montrer que cela fonctionne:
a.index(min(a))
n'. l'indice est une recherche...[1]
. Bien qu'il est difficile pour envelopper ma tête autour de la façon dont vous prévoyez sur le tri des choses, si vous ne voulez pas de les regarder...a.index
est parce que vous devez le faire afin d'utilisera.pop
. Suis-je malentendu vous?index
avec les listes-de-deux.pop
prend un entier (l'index) pour le placement de ce que vous voulez à la pop. Donc, sans l'aide dea.index
, vous obtiendrez l'erreur suivante:TypeError: an integer is required
a
liste dans l'ordre de la pop des trucs hors de lui. Il n'y a pas de point de trouver le max sur l'ensemble de la série. Il devrait être de trouver le max entre l'élément suivant sur chaque tuple. Voir mon auto-réponse de la direction que je suis à la recherche de prendre en. J'espère que ça le rend plus clair.Il est facile si vous n'essayez pas d'utiliser le fait que la plage interne listes sont triées
Il semble que vous voulez une fonction qui retourne l'indice de la plus petite valeur si
Je ne suis pas sûr de ce qui s'est passé mais je pense que tout le monde est un peu hors de la marque. Je vais le blâme sur qui font un mauvais travail en expliquant le problème, je vais essayer de résoudre. De toute façon, voici combien j'ai pris de l':
Cela me prend la plupart du chemin, mais de ce qu'il reste à traiter est le traitement de la situation où une seule liste a été épuisé. Une fois que c'est pris en charge il doit être facile pour en faire un générateur comme je peux juste le mettre dans une boucle et le rendement à l'intérieur, et aussi, espérons-le, sans trop de travail de plus elle peut être adaptée à l'exécution efficace de tri-fusion sur les générateurs.
Mise à jour:
Montage du sous-ensemble propre de encore valides-éléments de
min
est sur le billet.Exécutée:
Je vais noter cela peut encore être améliorée, la idxs liste est reconstruit à chaque itération. Il n'a pas besoin d'être, mais cela n'améliore pas la asymptotique lié... bien sûr, on peut se demander si nous nous soucions vraiment de la performance, si l'utilisation de la lambda est une bonne idée, bien que je ne vois vraiment pas un moyen de contourner cela sans prendre part
min
, qui est simplement une descente dans la folie.try
etexcept
et alors que vous venez de découvrir dont la liste est vide dans leexcept
et vous avez alors le reste!