it-swarm.com.de

Wie finde ich alle Positionen des Maximalwertes in einer Liste?

Ich habe eine Liste:

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]

max Element ist 55 (zwei Elemente auf Position 9 und 12)

Ich muss herausfinden, an welcher Position (en) der Maximalwert liegt. Bitte helfen.

110
Bob
>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]
167
SilentGhost
a.index(max(a))

gibt den Index der ersten Instanz des Elements mit dem höchsten Wert der Liste a an.

239
nmichaels

Die gewählte Antwort (und die meisten anderen) erfordern mindestens zwei Durchgänge durch die Liste.
Hier ist eine One-Pass-Lösung, die für längere Listen die bessere Wahl sein könnte. 

Überarbeitet: Um die beiden von @John Machin aufgezeigten Mängel zu beheben. Für (2) habe ich versucht, die Tests basierend auf der geschätzten Wahrscheinlichkeit des Auftretens jeder Bedingung und den von den Vorgängern erlaubten Schlüssen zu optimieren. Es war ein bisschen schwierig, die richtigen Initialisierungswerte für max_val und max_indices herauszufinden, was in allen möglichen Fällen funktioniert hat, insbesondere wenn der Maximalwert der erste Wert in der Liste war.

def maxelements(seq):
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if seq:
        max_val = seq[0]
        for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]

    return max_indices
18
martineau

Ich kann die @ SilentGhost-Leistung von @martineau nicht reproduzieren. Hier ist meine Mühe mit Vergleichen:

=== maxelements.py ===

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]
b = range(10000)
c = range(10000 - 1, -1, -1)
d = b + c

def maxelements_s(seq): # @SilentGhost
    ''' Return list of position(s) of largest element '''
    m = max(seq)
    return [i for i, j in enumerate(seq) if j == m]

def maxelements_m(seq): # @martineau
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if len(seq):
        max_val = seq[0]
        for i, val in ((i, val) for i, val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]
    return max_indices

def maxelements_j(seq): # @John Machin
    ''' Return list of position(s) of largest element '''
    if not seq: return []
    max_val = seq[0] if seq[0] >= seq[-1] else seq[-1]
    max_indices = []
    for i, val in enumerate(seq):
        if val < max_val: continue
        if val == max_val:
            max_indices.append(i)
        else:
            max_val = val
            max_indices = [i]
    return max_indices

Ergebnisse eines alten Notebooks, auf dem Python 2.7 unter Windows XP SP3 ausgeführt wird:

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_s(me.a)"
100000 loops, best of 3: 6.88 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_m(me.a)"
100000 loops, best of 3: 11.1 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_j(me.a)"
100000 loops, best of 3: 8.51 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_s(a100)"
1000 loops, best of 3: 535 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_m(a100)"
1000 loops, best of 3: 558 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_j(a100)"
1000 loops, best of 3: 489 usec per loop
8
John Machin

Ich habe mir folgendes ausgedacht und es funktioniert so, wie man es mit max, min und anderen Funktionen über Listen wie diese sehen kann:

Betrachten Sie also die nächste Beispielliste und finden Sie die Position des Maximum in der Liste a heraus:

>>> a = [3,2,1, 4,5]

Verwenden Sie den Generatorenumerate und machen Sie ein Casting

>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]

An dieser Stelle können wir die Position von max mit extrahieren

>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)

Das obige sagt uns, das Maximum ist in der Position 4 und sein Wert ist 5.

Wie Sie sehen, können Sie im Argument key das Maximum für jedes iterierbare Objekt ermitteln, indem Sie ein geeignetes Lambda definieren.

Ich hoffe, dass es dazu beiträgt.

PD: Wie @PaulOyster in einem Kommentar vermerkt. Mit Python 3.x Erlauben die min und max ein neues Schlüsselwort default, das die Ausnahmebedingung ValueError vermeidet, wenn das Argument leer ist. max(enumerate(list), key=(lambda x:x[1]), default = -1)

7
jonaprieto
a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 
         55, 23, 31, 55, 21, 40, 18, 50,
         35, 41, 49, 37, 19, 40, 41, 31]

import pandas as pd

pd.Series(a).idxmax()

9

So mache ich das normalerweise.

5
Arijit Laha

Sie können auch das Paket numpy verwenden:

import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))

Dadurch wird ein numpy-Array aller Indizes zurückgegeben, die den Maximalwert enthalten

wenn Sie dies zu einer Liste machen wollen:

maximum_indices_list = maximum_indices.tolist()
4
user3569257
>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1])
>>> (3, 32)
4
Hari Roshan

@shash hat das anderswo beantwortet

Eine pythonische Methode zum Ermitteln des Index des maximalen Listenelements wäre 

position = max(enumerate(a), key=lambda x: x[1])[0]

Welches passiert one. Es ist jedoch langsamer als die Lösung von @Silent_Ghost und vor allem @nmichaels:

for i in s m j n; do echo $i;  python -mtimeit -s"import maxelements as me" "me.maxelements_${i}(me.a)"; done
s
100000 loops, best of 3: 3.13 usec per loop
m
100000 loops, best of 3: 4.99 usec per loop
j
100000 loops, best of 3: 3.71 usec per loop
n
1000000 loops, best of 3: 1.31 usec per loop
2
serv-inc

Hier ist der Maximalwert und die Indizes, unter denen er erscheint:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> for i, x in enumerate(a):
...     d[x].append(i)
... 
>>> k = max(d.keys())
>>> print k, d[k]
55 [9, 12]

Später: zur Zufriedenheit von @SilentGhost

>>> from itertools import takewhile
>>> import heapq
>>> 
>>> def popper(heap):
...     while heap:
...         yield heapq.heappop(heap)
... 
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> h = [(-x, i) for i, x in enumerate(a)]
>>> heapq.heapify(h)
>>> 
>>> largest = heapq.heappop(h)
>>> indexes = [largest[1]] + [x[1] for x in takewhile(lambda large: large[0] == largest[0], popper(h))]
>>> print -largest[0], indexes
55 [9, 12]
2
hughdbrown

Eine ähnliche Idee mit einem Listenverständnis, aber ohne aufzählen

m = max(a)
[i for i in range(len(a)) if a[i] == m]
2
Salvador Dali

Nur eine Zeile:

idx = max(range(len(a)), key = lambda i: a[i])
2
divkakwani

Sie können es auf verschiedene Arten tun.

Der alte herkömmliche Weg ist

maxIndexList = list() #this list will store indices of maximum values
maximumValue = max(a) #get maximum value of the list
length = len(a)       #calculate length of the array

for i in range(length): #loop through 0 to length-1 (because, 0 based indexing)
    if a[i]==maximumValue: #if any value of list a is equal to maximum value then store its index to maxIndexList
        maxIndexList.append(i)

print(maxIndexList) #finally print the list

Eine andere Möglichkeit, ohne die Länge der Liste zu berechnen und den Maximalwert in einer Variablen zu speichern

maxIndexList = list()
index = 0 #variable to store index
for i in a: #iterate through the list (actually iterating through the value of list, not index )
    if i==max(a): #max(a) returns a maximum value of list.
        maxIndexList.append(index) #store the index of maximum value
index = index+1 #increment the index

print(maxIndexList)

Wir können es auf Pythonic und auf intelligente Weise tun! Listenverständnis nur in einer Zeile verwenden,

maxIndexList = [i for i,j in enumerate(a) if j==max(a)] #here,i=index and j = value of that index

Alle meine Codes sind in Python 3.

0
Taohidul Islam
import operator

def max_positions(iterable, key=None, reverse=False):
  if key is None:
    def key(x):
      return x
  if reverse:
    better = operator.lt
  else:
    better = operator.gt

  it = enumerate(iterable)
  for pos, item in it:
    break
  else:
    raise ValueError("max_positions: empty iterable")
    # note this is the same exception type raised by max([])
  cur_max = key(item)
  cur_pos = [pos]

  for pos, item in it:
    k = key(item)
    if better(k, cur_max):
      cur_max = k
      cur_pos = [pos]
    Elif k == cur_max:
      cur_pos.append(pos)

  return cur_max, cur_pos

def min_positions(iterable, key=None, reverse=False):
  return max_positions(iterable, key, not reverse)

>>> L = range(10) * 2
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> max_positions(L)
(9, [9, 19])
>>> min_positions(L)
(0, [0, 10])
>>> max_positions(L, key=lambda x: x // 2, reverse=True)
(0, [0, 1, 10, 11])
0
Roger Pate

Dieser Code ist nicht so komplex wie die Antworten, die zuvor veröffentlicht wurden, aber er wird funktionieren:

m = max(a)
n = 0    # frequency of max (a)
for number in a :
    if number == m :
        n = n + 1
ilist = [None] * n  # a list containing index values of maximum number in list a.
ilistindex = 0
aindex = 0  # required index value.    
for number in a :
    if number == m :
        ilist[ilistindex] = aindex
        ilistindex = ilistindex + 1
    aindex = aindex + 1

print ilist

ilist im obigen Code würde alle Positionen der maximalen Anzahl in der Liste enthalten.

0
Sukrit Gupta

Wenn Sie die Indizes der größten n-Nummern in einer Liste namens data erhalten möchten, können Sie Pandas sort_values verwenden:

pd.Series(data).sort_values(ascending=False).index[0:n]
0
dannyg