函数错误从数字列表返回3个最大值

时间:2015-12-14 13:11:44

标签: python numbers max

我有这个数据文件,我必须找到它包含的3个最大数字

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

因此我编写了以下代码,但它只搜索第一行数字而不是整个列表。任何人都可以帮忙找到错误吗?

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"))

4 个答案:

答案 0 :(得分:12)

您的数据包含的float个数字不是integer

您可以使用sorted

>>> 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]

如果您想integer结果

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

答案 1 :(得分:8)

您只获得第一行的最大元素,因为您在第一次迭代结束时返回。你应该去掉缩进语句。

对数据进行排序并选择前3个元素在n * log(n)中运行。

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

144个元素完全没问题。 您还可以使用heapq

以线性时间获得答案
import heapq
heapq.nlargest(3, data)

答案 2 :(得分:7)

您的return语句位于for循环内。一旦达到返回,函数就会终止,因此循环永远不会进入第二次迭代。通过减少缩进将return移到循环外部。

    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

此外,您的比较将不起作用,因为line.split()返回字符串列表,而不是浮点数。 (正如已经指出的那样,你的数据由浮点数组成,而不是整数。我假设任务是找到最大的浮点数。)所以让我们使用float()转换字符串

但是,您的代码仍然不正确,因为当您找到新的最大值时,您将完全丢弃旧代码。相反,你现在应该认为它是已知的第二大值。同样的规则适用于第二到第三大。

    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

现在还有最后一个问题:

您忽略了我与其中一个最大值相同的情况。在这种情况下,i > largest将是错误的,但largest > i也是如此。您可以将这些比较中的任何一个更改为>=来解决此问题。

相反,让我们通过考虑仅在已发现所有先前条件为假之后才考虑if条件来简化elif子句。当我们到达第一个elif时,我们已经知道i不能大于largest,因此将其与second largest进行比较就足够了。第二个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

这样我们就可以避免意外过滤出i == largesti == second_largest边缘情况。

答案 3 :(得分:1)

由于您正在处理文件,因此您可以将文件作为数组加载,然后对数组进行排序并获取最后3项:

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

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