1

A set of 13 sensors transmit numerical data that is read every 5 minutes. To capture these values I used a dictionary of lists:

Sensors = {
         'Sensor1':[10.52,12.45,15.70],
         'Sensor5':[12.32,22.80,30.42],
         'Sensor3':[4.7,3.4,2.1],
         'Sensor8':[2.34,4.28,7.10],
         'Sensor4':[10.64,14.76,4.25],
         'Sensor2':[3.21,7.88,9.22],
         'Sensor6':[4.11,9.32,2.70],
         'Sensor9':[11.45,14.72,8.30],
         'Sensor7':[6.10,3.98,10.66],
         'Sensor10':[7.22,8.67,10.99],
         'Sensor13':[1.19,4.65,0.87],
         'Sensor12':[2.10,5.46,3.21],
         'Sensor11':[5.80,8.22,14.39]
         }

I need to sort this list so that the sensors that have had a positive increase appear at the top. To achieve this goal, I created another dictionary DeltaValues with the name of the sensor and the difference between the last and the first value captured:

 DeltaValues={}
  for x, y in Sensors.items():
      if len(y) > 1:
         DeltaValues[x] = format(y[-1] - y[0],'.2f')
      else:
         DeltaValues[x] = format(y[0],'.2f')

I used this syntax to sort:

sorted_d = {k: v for k, v in sorted(DeltaValues.items(), key=lambda x: x[1])}

But the result was not what I expected:

print(sorted_d)

{'Sensor13': '-0.32',
 'Sensor6': '-1.41',
 'Sensor3': '-2.60',
 'Sensor9': '-3.15',
 'Sensor4': '-6.39',
 'Sensor12': '1.11',
 'Sensor5': '18.10',
 'Sensor10': '3.77',
 'Sensor7': '4.56',
 'Sensor8': '4.76',
 'Sensor1': '5.18',
 'Sensor2': '6.01',
 'Sensor11': '8.59'}
bonzix
  • 45
  • 5
  • What is your expected output? – ggorlen Jun 14 '19 at 22:00
  • You should sort sequences like lists, not mappings. A dictionary has no order in its elements (and if it has that's an implementation detail, I am adding this because recently Python dicts become ordered) – progmatico Jun 14 '19 at 22:00
  • They are sorted as strings (because they are strings). Don't call `format` to round them, call `round` instead. – Blorgbeard Jun 14 '19 at 22:06

4 Answers4

2

Dicts do not guarantee to return the values in order in which they were put in.

Consider ordered dict. https://docs.python.org/3/library/collections.html#collections.OrderedDict

knalj
  • 1,454
  • 1
  • 10
  • 14
2

You could sort the (key, value) pairs and leave them in a list:

>>> sorted(Sensors.items(), key= lambda sensor:sensor[1][-1] - sensor[1][0])
[('Sensor4', [10.64, 14.76, 4.25]), ('Sensor9', [11.45, 14.72, 8.3]), ('Sensor3', [4.7, 3.4, 2.1]), ('Sensor6', [4.11, 9.32, 2.7]), ('Sensor13', [1.19, 4.65, 0.87]), ('Sensor12', [2.1, 5.46, 3.21]), ('Sensor10', [7.22, 8.67, 10.99]), ('Sensor7', [6.1, 3.98, 10.66]), ('Sensor8', [2.34, 4.28, 7.1]), ('Sensor1', [10.52, 12.45, 15.7]), ('Sensor2', [3.21, 7.88, 9.22]), ('Sensor11', [5.8, 8.22, 14.39]), ('Sensor5', [12.32, 22.8, 30.42])]
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
1

Here is the solution

import operator
def getSortedSensorData():
    sensors = {
         'Sensor1':[10.52,12.45,15.70],
         'Sensor5':[12.32,22.80,30.42],
         'Sensor3':[4.7,3.4,2.1],
         'Sensor8':[2.34,4.28,7.10],
         'Sensor4':[10.64,14.76,4.25],
         'Sensor2':[3.21,7.88,9.22],
         'Sensor6':[4.11,9.32,2.70],
         'Sensor9':[11.45,14.72,8.30],
         'Sensor7':[6.10,3.98,10.66],
         'Sensor10':[7.22,8.67,10.99],
         'Sensor13':[1.19,4.65,0.87],
         'Sensor12':[2.10,5.46,3.21],
         'Sensor11':[5.80,8.22,14.39]
         }

    sensorData = {};

    for sensor in sensors:
        data = sensors[sensor]
        data = sorted(data, reverse = True)
        sensorData[sensor] = data[0];

    sensorData = sorted( sensorData.items(), key=operator.itemgetter(1),reverse=True ) 
    print( sensorData )

Output

[('Sensor5', 30.42), ('Sensor1', 15.7), ('Sensor4', 14.76), ('Sensor9', 14.72), ('Sensor11', 14.39), ('Sensor10', 10.99), ('Sensor7', 10.66), ('Sensor6', 9.32), ('Sensor2', 9.22), ('Sensor8', 7.1), ('Sensor12', 5.46), ('Sensor3', 4.7), ('Sensor13', 4.65)]

Haseeb Afsar
  • 619
  • 5
  • 7
1

If you are on python 3.5+, use regular dict as follows:

dict(sorted(Sensors.items(), key=lambda x: x[1][-1] - x[1][0], reverse=True))

Out[11]:
{'Sensor5': [12.32, 22.8, 30.42],
 'Sensor11': [5.8, 8.22, 14.39],
 'Sensor2': [3.21, 7.88, 9.22],
 'Sensor1': [10.52, 12.45, 15.7],
 'Sensor8': [2.34, 4.28, 7.1],
 'Sensor7': [6.1, 3.98, 10.66],
 'Sensor10': [7.22, 8.67, 10.99],
 'Sensor12': [2.1, 5.46, 3.21],
 'Sensor13': [1.19, 4.65, 0.87],
 'Sensor6': [4.11, 9.32, 2.7],
 'Sensor3': [4.7, 3.4, 2.1],
 'Sensor9': [11.45, 14.72, 8.3],
 'Sensor4': [10.64, 14.76, 4.25]}

If you are on python < 3.5+, use collecions.OrderedDict as follows:

collections.OrderedDict(sorted(Sensors.items(), key=lambda x: x[1][-1] - x[1][0], reverse=True))

Out[2067]:
OrderedDict([('Sensor5', [12.32, 22.8, 30.42]),
             ('Sensor11', [5.8, 8.22, 14.39]),
             ('Sensor2', [3.21, 7.88, 9.22]),
             ('Sensor1', [10.52, 12.45, 15.7]),
             ('Sensor8', [2.34, 4.28, 7.1]),
             ('Sensor7', [6.1, 3.98, 10.66]),
             ('Sensor10', [7.22, 8.67, 10.99]),
             ('Sensor12', [2.1, 5.46, 3.21]),
             ('Sensor13', [1.19, 4.65, 0.87]),
             ('Sensor6', [4.11, 9.32, 2.7]),
             ('Sensor3', [4.7, 3.4, 2.1]),
             ('Sensor9', [11.45, 14.72, 8.3]),
             ('Sensor4', [10.64, 14.76, 4.25])])
Andy L.
  • 24,909
  • 4
  • 17
  • 29