Seite 1 von 1

die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Mittwoch 3. April 2019, 20:55
von winnitouch
Hallo zusammen,

habe aktuell folgendes Problem.
Ich hab 2 Listen. Die erste Liste enthält Kontostände. Also zum Beispiel so:
[500, 700, 800, 650, 1000, 1500, 2400, 1750, 1800, 1900]

Daraus generiere ich eine zweite Liste, welche gemäss der Kontostandsliste den Gewinn/Verlust ermittelt, also wäre das so:
[500, 200, 100, -150, 350, 500, 900, -650, 50, 100]

Nun möchte ich die x (am besten beliebig einstellbar via Input zum Beispiel) grössten und kleinsten Werte aus der Gewinn/Verlust Liste entfernen und entsprechend eine korrekte, neue Kontostandsliste bauen.

Nun, wenn man für x einen festen Wert annimmt, dann hab ich eine (ziemlich) unelegante Lösung.

Mal angenommen, man nimmt für x = 2 an, dann lass ich 2 mal folgende Schleife für die max-Werte laufen, dann noch 2 mal für die Min werte, und dann bastel ich daraus eine neue Kontostandsliste. Das kommt mir aber maximal umständlich vor und es ist wie gesagt nicht dynamisch für x.

Code: Alles auswählen

    
#max-werte entfernen
for c in range(0,len(list_gewinn_verlust)):
    if list_gewinn_verlust[c] == max(list_gewinn_verlust):
         list_gewinn_verlust.pop(c)
         break
for c in range(0,len(list_gewinn_verlust)):
    if list_gewinn_verlust[c] == max(list_gewinn_verlust):
         list_gewinn_verlust.pop(c)
         break
         
#min-werte entfernen
for c in range(0,len(list_gewinn_verlust)):
    if list_gewinn_verlust[c] == min(list_gewinn_verlust):
         list_gewinn_verlust.pop(c)
         break
for c in range(0,len(list_gewinn_verlust)):
    if list_gewinn_verlust[c] == min(list_gewinn_verlust):
         list_gewinn_verlust.pop(c)
         break
Hat mir jemand eine elegante Lösung für das Problem mit dynamisch möglichem x?

Gruss

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Mittwoch 3. April 2019, 21:08
von Sirius3
Wenn man etwas mehrfach wiederholen will, benutzt man eine Schleife, wie Du es ja schon tust.
Das was Du tust ist sehr ineffizient, weil Du für jedes Element neu den Maximalwert berechnest.

Eine Schleife läßt sich auch durch remove ersetzen:

Code: Alles auswählen

list_gewinn_verlust.remove(max(list_gewinn_verlust))

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Mittwoch 3. April 2019, 21:12
von __deets__
So zb:

Code: Alles auswählen

import operator
kontostand = [500, 700, 800, 650, 1000, 1500, 2400, 1750, 1800, 1900]

margin = 2 
tagged = sorted([(v, i) for i, v in enumerate(kontostand)])
clipped = [v for v, _ in sorted(tagged[margin:-margin], key=operator.itemgetter(1))]
print(clipped)

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 04:38
von snafu
Ich würde das wohl so machen:

Code: Alles auswählen

sorted(gewinn_verlust)[x:-x]
Damit wird die Liste nach Größe sortiert. Anschließend werden die Werte ab dem x-ten Element geliefert und es wird beim x-letzten Wert gestoppt. Wenn x=2 ist, dann erhälst du also alles ab dem zweiten Element bis zum vorvorletzten Element.

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 07:00
von kbr
@snafu: Das musst Du schon so machen wie __deets__, wenn nach entfernen der Extrema die ursprüngliche Reihenfolge der verbleibenden Elemente wieder hergestellt werden soll.

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 15:44
von snafu
Dann könnte man sich bei meinem Ansatz das sortierte Ergebnis merken und anschließend das Original durchlaufen:

Code: Alles auswählen

relevant = set(sorted(gewinn_verlust)[x:-x])
print([wert for wert in gewinn_verlust if wert in relevant])

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 15:54
von __blackjack__
@snafu: Da kann dann aber mehr entfernt werden als 2x Werte. Im Extremfall hat man am Ende sogar eine komplett leere Liste.

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 16:00
von __deets__
Mehr entfernt habe ich jetzt nicht so gesehen, aber zu viele beibehalten, wie dieses Beispiel schoen illustriert:

Code: Alles auswählen

x = 2
gewinn_verlust = [10]*10
relevant = sorted(gewinn_verlust)[x:-x]
ergebnis = [wert for wert in gewinn_verlust if wert in relevant]
print(gewinn_verlust == ergebnis) # True

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 16:03
von snafu
__blackjack__ hat geschrieben: Donnerstag 4. April 2019, 15:54 @snafu: Da kann dann aber mehr entfernt werden als 2x Werte. Im Extremfall hat man am Ende sogar eine komplett leere Liste.
Die Rede war ja nicht davon, dass x-mal zwei Elemente entfernt werden sollen, sondern halt die mit den x-größten und x-kleinsten Werten. Da wäre es IMHO nicht falsch, wenn bei doppelten Extremwerten zusätzliche Elemente rausfallen.

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 16:10
von snafu
@__deets__: Da muss ich dir Recht geben. Den Fall hatte ich nicht bedacht. Hier ist dein Code robuster, wenn auch komplizierter.

Wobei natürlich die Frage ist, ob bei deinem 10er-Beispiel am Ende vielleicht besser eine leere Liste herauskommen sollte.

Re: die x grössten und kleinsten Werte aus Liste entfernen

Verfasst: Donnerstag 4. April 2019, 16:11
von __deets__
Das vom TE dargestellte Verhalten ist das aber eben nicht. Er hat einen muehseligen Weg gefunden, aber es fliegt jeweils nur *ein* Element raus, und das dann x-mal. Und nicht beliebig oft mal.