2015-12-14 7 views
14

ich diese Datendatei haben, und ich habe die drei größten Zahlen zu finden, esFehler in Funktion zurückzukehren 3 größten Werte aus einer Liste von Zahlen

24.7 25.7 30.6 47.5 62.9 68.5 73.7 67.9 61.1 48.5 39.6 20.0 
16.1 19.1 24.2 45.4 61.3 66.5 72.1 68.4 60.2 50.9 37.4 31.1 
10.4 21.6 37.4 44.7 53.2 68.0 73.7 68.2 60.7 50.2 37.2 24.6 
21.5 14.7 35.0 48.3 54.0 68.2 69.6 65.7 60.8 49.1 33.2 26.0 
19.1 20.6 40.2 50.0 55.3 67.7 70.7 70.3 60.6 50.7 35.8 20.7 
14.0 24.1 29.4 46.6 58.6 62.2 72.1 71.7 61.9 47.6 34.2 20.4 
8.4  19.0 31.4 48.7 61.6 68.1 72.2 70.6 62.5 52.7 36.7 23.8 
11.2 20.0 29.6 47.7 55.8 73.2 68.0 67.1 64.9 57.1 37.6 27.7 
13.4 17.2 30.8 43.7 62.3 66.4 70.2 71.6 62.1 46.0 32.7 17.3 
22.5 25.7 42.3 45.2 55.5 68.9 72.3 72.3 62.5 55.6 38.0 20.4 
17.6 20.5 34.2 49.2 54.8 63.8 74.0 67.1 57.7 50.8 36.8 25.5 
20.4 19.6 24.6 41.3 61.8 68.5 72.0 71.1 57.3 52.5 40.6 26.2 

enthält Deshalb habe ich den folgenden Code geschrieben, aber es nur Sucht die erste Zahlenreihe anstelle der gesamten Liste. Kann jemand helfen, den Fehler zu finden?

def three_highest_temps(f): 
    file = open(f, "r") 
    largest = 0 
    second_largest = 0 
    third_largest = 0 
    temp = [] 
    for line in file: 
     temps = line.split() 

     for i in temps: 
      if i > largest: 
       largest = i 
      elif largest > i > second_largest: 
       second_largest = i 
      elif second_largest > i > third_largest: 
       third_largest = i 
     return largest, second_largest, third_largest 

print(three_highest_temps("data5.txt")) 
+0

Die sehen für mich nicht wie ganze Zahlen aus. –

+1

Sie sollten die Werte mit 'float ('- inf')' initialisieren. Sonst könnte es zu Problemen kommen, wenn der größte Wert eines Tages negativ ist. – moooeeeep

Antwort

7

Ihre return Aussage ist in der for Schleife möchten. Sobald die Rückgabe erreicht ist, wird die Funktion beendet, so dass die Schleife niemals in eine zweite Iteration übergeht. Verschieben Sie die return außerhalb der Schleife, indem Sie die Einrückung reduzieren.

for line in file: 
     temps = line.split() 

     for i in temps: 
      if i > largest: 
       largest = i 
      elif largest > i > second_largest: 
       second_largest = i 
      elif second_largest > i > third_largest: 
       third_largest = i 
    return largest, second_largest, third_largest 

Darüber hinaus wird Ihre Vergleiche nicht, weil line.split() eine Liste von Strings zurückgibt, nicht schwimmt. (Wie bereits erwähnt, bestehen Ihre Daten aus Floats, nicht aus Ints. Ich nehme an, dass die Aufgabe darin besteht, die Strings mit float()

zu konvertieren. Ihr Code wird immer noch nicht korrekt sein. Wenn Sie jedoch einen neuen größten Wert finden, verwerfen Sie den alten Wert vollständig. Stattdessen sollten Sie es jetzt als den zweitgrößten bekannten Wert betrachten. Für die zweit- bis drittgrößte gilt die gleiche Regel.

for line in file: 
     temps = line.split() 

     for temp_string in temps: 
      i = float(temp_string) 
      if i > largest: 
       third_largest = second_largest 
       second_largest = largest 
       largest = i 
      elif largest > i > second_largest: 
       third_largest = second_largest 
       second_largest = i 
      elif second_largest > i > third_largest: 
       third_largest = i 
    return largest, second_largest, third_largest 

Jetzt gibt es noch eine letzte Frage:

Sie Fälle übersehen, wo ich mit einer der größten Werte identisch ist. In einem solchen Fall wäre i > largest falsch, aber auch largest > i. Sie können einen dieser Vergleiche auf >= ändern, um dies zu beheben.

Lassen Sie uns stattdessen die if Klauseln vereinfachen, indem Sie berücksichtigen, dass die elif Bedingungen nur berücksichtigt werden, nachdem alle vorherigen Bedingungen bereits als falsch gefunden wurden. Als wir die erste elif erreichen, wissen wir bereits, dass i nicht größer als largest sein kann, so dass es ausreicht, es mit second largest zu vergleichen. Das gleiche gilt für die zweite elif.

for line in file: 
     temps = line.split() 

     for temp_string in temps: 
      i = float(temp_string) 
      if i > largest: 
       third_largest = second_largest 
       second_largest = largest 
       largest = i 
      elif i > second_largest: 
       third_largest = second_largest 
       second_largest = i 
      elif i > third_largest: 
       third_largest = i 
    return largest, second_largest, third_largest 

diese Weise können wir die i == largest und i == second_largest Rand Fällen versehentlich Ausfiltern vermeiden.

+0

dies gibt zurück (8.2, 73.0, 72.7) aus irgendeinem Grunde im Grunde für i in temps: es ist die Spaltenaufteilung der Daten, aber es überprüft nicht alle – Sinoda

+0

Sie vergleichen Strings im Moment. Du musst 'i' in einen float umwandeln –

+0

wie würde ich das machen, wenn ich [float (i) für i in temps] verwende: es wirft alles weg – Sinoda

12

Ihre Daten enthält float Zahlen nicht integer.

können Sie sorted verwenden:

>>> data = '''24.7 25.7 30.6 47.5 62.9 68.5 73.7 67.9 61.1 48.5 39.6 20.0 
... 16.1 19.1 24.2 45.4 61.3 66.5 72.1 68.4 60.2 50.9 37.4 31.1 
... 10.4 21.6 37.4 44.7 53.2 68.0 73.7 68.2 60.7 50.2 37.2 24.6 
... 21.5 14.7 35.0 48.3 54.0 68.2 69.6 65.7 60.8 49.1 33.2 26.0 
... 19.1 20.6 40.2 50.0 55.3 67.7 70.7 70.3 60.6 50.7 35.8 20.7 
... 14.0 24.1 29.4 46.6 58.6 62.2 72.1 71.7 61.9 47.6 34.2 20.4 
... 8.4  19.0 31.4 48.7 61.6 68.1 72.2 70.6 62.5 52.7 36.7 23.8 
... 11.2 20.0 29.6 47.7 55.8 73.2 68.0 67.1 64.9 57.1 37.6 27.7 
... 13.4 17.2 30.8 43.7 62.3 66.4 70.2 71.6 62.1 46.0 32.7 17.3 
... 22.5 25.7 42.3 45.2 55.5 68.9 72.3 72.3 62.5 55.6 38.0 20.4 
... 17.6 20.5 34.2 49.2 54.8 63.8 74.0 67.1 57.7 50.8 36.8 25.5 
... 20.4 19.6 24.6 41.3 61.8 68.5 72.0 71.1 57.3 52.5 40.6 26.2 
... ''' 

>>> sorted(map(float, data.split()), reverse=True)[:3] 
[74.0, 73.7, 73.7] 

Wenn Sie integer Ergebnisse

>>> temps = sorted(map(float, data.split()), reverse=True)[:3] 
>>> map(int, temps) 
[74, 73, 73] 
+1

'Heapq.nlargest' ist effizienter für große Liste. – eph

+0

@eph Eigentlich ist es keine große Liste, '144 Artikel' –

8

Sie erhalten nur die maximalen Elemente für die erste Zeile, weil Sie am Ende der ersten Iteration zurückkehren. Sie sollten die return-Anweisung rückgängig machen.

Die Sortierung der Daten und die Auswahl der ersten drei Elemente erfolgt in n * log (n).

data = [float(v) for v in line.split() for line in file] 
sorted(data, reverse=True)[:3] 

Es ist völlig in Ordnung für 144 Elemente. Sie können auch die Antwort in linearer Zeit erhalten eine heapq mit

import heapq 
heapq.nlargest(3, data) 
+0

Ja, es ist besser. +1 :) –

1

Da Sie mit einer Datei handelt, als Guss und numpythonic Ansatz Sie die Datei als Array laden und dann das Array sortieren und erhalten die Letzte 3 Artikel:

import numpy as np 
with open('filename') as f: 
    array = np.genfromtxt(f).ravel() 
    array.sort() 

print array[-3:] 
[ 73.7 73.7 74. ] 
Verwandte Themen