2

I have a nested list like so:

temperature = [["Jan", 12, 18, 16, 18], ["Feb", 10, 20, 50, 50], ["Mar", 23, 32, 10, 32]]

the list contains all the months up until December with the 3 highest temp recorded over the entire month and then the highest out of the 3 appended to the end of the list.

I have worked out the highest temp for each month in the following way:

def sortTemp():
    for temp in temperatures:
        temp = [temp[0], temp[4]]
        highest.append(temp)
    highest.sort()
    print(highest)

This works, however I had to work out the max values beforehand, and append it to the temperature list as explained above. Is there an easier way to do this?

Also, how do I work out the average temp of each month using the data provided in the temperature list, sorted by the highest average?

Output should be like:

AverageTemp = [["Month", AverageTemp], ["Month", AverageTemp]] 
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
PythonNewBee
  • 143
  • 1
  • 7

4 Answers4

2

You can use a list comprehension to compute the averages

>>> AverageTemp = [[i[0], sum(i[1:])/len(i[1:])] for i in temperature]
>>> AverageTemp
[['Jan', 16.0], ['Feb', 32.5], ['Mar', 24.25]]

Or if you have numpy

>>> import numpy as np
>>> AverageTemp = [[i[0], np.mean(i[1:])] for i in temperature]
>>> AverageTemp
[['Jan', 16.0], ['Feb', 32.5], ['Mar', 24.25]]

Then to sort you can use the key and reverse arguments

>>> AverageTemp = sorted([[i[0], np.mean(i[1:])] for i in temperature], key = lambda i: i[1], reverse = True)
>>> AverageTemp
[['Feb', 32.5], ['Mar', 24.25], ['Jan', 16.0]]
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Can you please explain your code? I am having problems with understanding list comprehension. – PythonNewBee Jun 04 '15 at 19:27
  • Is there anything specific in the list comprehension that is unclear? Or are you unfamiliar with the syntax of a list comprehension in general? – Cory Kramer Jun 04 '15 at 19:29
  • i am finding the syntax difficult to understand in general for the list comprehension...I really want to learn and understand the code. – PythonNewBee Jun 04 '15 at 19:32
  • 1
    Read through the Python docs on [List Comprehensions](https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions) – Synergist Jun 04 '15 at 19:34
  • You can solve your maximum problem similarly, `MaxTemps = [[i[0], max(i[1:])] for i in temperature]`....or if the max temp is already placed in the 4th position for you, `MaxTemps = [[i[0], i[3]] for i in temperature]` – Synergist Jun 04 '15 at 19:36
  • Thank you very much guys, really appreciate the quick response. – PythonNewBee Jun 04 '15 at 19:46
  • For the average, this processes all the temperatures `[1:]`, but the last temperature in the list is merely a repeat of the maximum temperature, resulting in an inflated value. – TigerhawkT3 Jun 04 '15 at 20:11
1

You can use a list comprehension within sorted function :

>>> from operator import itemgetter
>>> sorted([[l[0],sum(l[1:])/4]for l in temperature],key=itemgetter(1),reverse=True)
[['Feb', 32], ['Mar', 24], ['Jan', 16]]

In preceding code you first loop over your list then get the first element and the avg of the rest by [l[0],sum(l[1:])/4] and use operator.itemgetter as the key of your sorted function to sort your result based on the second item (the average)

Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • This has the same issue as Cory's: it includes a repeat of the maximum temperature when calculating the average. – TigerhawkT3 Jun 04 '15 at 20:13
0

Understanding more about list comprehension and slice notation will really help you do this simply with pythonic code.

To explain @CoryKramer's first answer:

>>> AverageTemp = [[i[0], sum(i[1:4])/len(i[1:4])] for i in temperature]
>>> AverageTemp
[['Jan', 15], ['Feb', 26], ['Mar', 21]]

What he is doing is using i to cycle through the lists in temperature (which is a list of lists) and then using slice notation to get the info you need. So, obviously i[0] is your month, but the notation sum(i[1:4]) gets the sum of the items in the list from index 1 to the 3 using slice notation. He then divides by the length and creates the list of lists AverageTemp with the information you need.

Note: I have edited his answer to not include the high temperature twice per the comment from @TigerhawkT3.

Community
  • 1
  • 1
jdf
  • 699
  • 11
  • 21
  • Thanks so much for all the support guys, this was the first question I asked and the support is invaluable. I have learnt lots from asking the question. Thanks especially for the explanation jdfLemon and all others. – PythonNewBee Jun 04 '15 at 20:52
  • @PythonNewBee, just keep in mind that most of the answers are providing averages with the maximum temperature counted twice. – TigerhawkT3 Jun 04 '15 at 21:07
0

That's not a very good structure for the given data: you have differentiated items (name of a month, temperatures, maximum temperature) as undifferentiated list elements. I would recommend dictionaries or objects.

months = {"Jan":[12, 18, 16], "Feb":[10, 20, 50], "Mar":[23, 32, 10]}
for month in sorted(months, key=lambda x: sum(months.get(x))/len(months.get(x)), reverse=True):
    temps = months.get(month)
    print(month, max(temps), sum(temps)/len(temps))

Result:

Feb 50 26.666666666666668
Mar 32 21.666666666666668
Jan 18 15.333333333333334

class Month:
    def __init__(self, name, *temps):
        self.name = name
        self.temps = temps
    def average(self):
        return sum(self.temps)/len(self.temps)
    def maximum(self):
        return max(self.temps)
months = [Month('Jan', 12, 18, 16), Month('Feb', 10, 20, 50), Month('Mar', 23, 32, 10)]
for month in sorted(months, key=lambda x: x.average(), reverse=True):
    print(month.name, month.maximum(), month.average())

Result:

Feb 50 26.666666666666668
Mar 32 21.666666666666668
Jan 18 15.333333333333334
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97