2016-08-26 4 views
1

Ich habe eine Funktion, die eine Liste und entfernt (eine Instanz von) die kleinsten und größten Elemente, dann nimmt den Durchschnitt der übrigen Elemente. Das Ausführen von es bringt keine Fehler, obwohl bei der Überprüfung der Ergebnisse erkannte ich, dass sie falsch waren. Hier ist das Programm:Index 1/2. Listenelement wird ohne ersichtlichen Grund übersprungen

def centered_average(x): 
    x.sort() 
    y = 0 
    for i in x: 
     if x.index(i) == 0 or x.index(i) == (len(x)-1): 
      print(i, "is being removed") 
      x.remove(i) 
      i +=1 
     else: 
      y += i 
      print(i, "is being added") 
    return (y/len(x)) 

def average(x): 
    return sum(x)/len(x) 

über die Umsetzung durch eine Liste von

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

das Ergebnis war (die Druckfunktionen wurden zur Überprüfung gestellt in):

1 is being removed 
3 is being added 
4 is being added 
5 is being removed 
2.3333333333333335 

Daher können wir annehmen, dass x [1] in der Funktion nicht verwendet wird, und ich würde gerne wissen w warum.

Vielen Dank im Voraus für jede Hilfe.

+0

Was soll das i + = 1 tun? (Ich meine, was denkst du sollte es tun) – Julien

+0

Deine Frage fehlt eindeutig eine zentrale Sache: was willst du * tun? Es gibt ein paar Probleme, die Sie mit Ihrem Code beheben sollten, aber es bringt nichts, sie zu erklären, ohne zu wissen, was Sie überhaupt tun wollten. –

+0

Ich bin nicht sicher, warum ich es einfüge, aber das Entfernen gibt das gleiche Ergebnis zurück –

Antwort

3

Sie müssen besondere Vorsicht walten lassen, wenn Sie Elemente einer Liste entfernen, die Sie bereits in Python durchlaufen, wie Sie es in Ihrer Funktion tun. Python betrachtet die Indizes der Liste und verwendet diese, aber wenn Sie das erste Element entfernen und die Liste an Ort und Stelle aktualisiert wird, ist das vorherige zweite Element (x[1]) jetzt das erste (x[0]) und wird daher übersprungen.

Es gibt eine einfachere Möglichkeit, dies zu tun, die jedoch keine solche Schleife und die zusätzlichen Bedingungen erfordert, wenn Sie nur den Durchschnitt der Elemente verwenden möchten, die nicht die ersten oder letzten sind:

def centered_average(x): 
    x.sort() 
    if len(x) <= 2: 
     print "Cannot run with 2 or fewer elements..." 
     return 0 
    else: 
     return sum(x[1:-1])/(len(x)-2.00) 

Es gibt andere Wege, dies zu tun, aber diese sollte schnell genug sein und ermöglicht jeden Fall, dass Sie so lange bieten als x eine Liste ist. Hoffe das hilft.

+0

oh ok das macht Sinn. Mir wurde geraten, dass mein Fehler mit dem remove() -Teil zu tun habe, aber ich wusste nicht, wie. Danke vielmals! –

+0

Kein Problem, wenn dies für Ihren Code funktioniert, akzeptieren Sie bitte die Antwort, so dass die Frage als gelöst angezeigt wird und die Diskussion nicht weiterführt, wenn Sie damit fertig sind. – dblclik

1

Das Problem kommt von der for i in x:. Wenn Sie das erste Element entfernen, wird das zweite Element (2) zum ersten Element der Liste. Dies bedeutet, dass Sie bei der nächsten Iteration nach dem zweiten Element suchen und 3 suchen, da die Liste jetzt [2, 3, 4, 5] ist.

Stattdessen könnten Sie beginnen, indem Sie das erste und letzte Element mit x=x[1:-1] entfernen. Wenn Sie die [i:-j]-Syntax zuvor noch nie gesehen haben, wird Python angewiesen, eine Liste beginnend mit Index i und endend mit j Indizes am Ende zurückzugeben. Mit anderen Worten, dies wird [2, 3, 4] in Ihrem Beispiel erzeugen. Danach können Sie sum(x)/len(x) zurückgeben.

Beachten Sie, dass weder dieser Code noch Ihr ursprünglicher Ansatz auf Listen mit weniger als 3 Elementen funktioniert. Wenn Sie in beiden Lösungen durch len(x) dividieren, werden Sie am Ende durch 0 dividieren.

+1

Beachten Sie, dass 'sum (x)/len (x)' nur eine Ganzzahl und keinen Gleitkommawert liefert –

+0

Guter Punkt. Wenn Sie dezimale Ergebnisse wünschen, können Sie stattdessen float (len (x)) verwenden. Etwas wie len (x) * 1.0 würde auch funktionieren, aber ich finde es weniger Pythonic. – ScottWe

Verwandte Themen