eamon1234
eamon1234

Reputation: 1585

Python data structure advice

I have a fairly basic question regarding python lists/dictionaries which I would like some help on.

I have some data relating to electric vehicles which have different characteristics. Each EV has an:

How best do I go about this? I had been trying various combinations of lists/dicts but can't quite get it to work. I'd like to be able to access the data by e.g.:

EV['ID'][2]['Batt']['SOC'][5] which would return e.g. 0.95 or
EV[12345]['Batt']['SOC'][5]

My latest attempt was:

EV = defaultdict(lambda: defaultdict(dict))

EV['ID']['Batt']['Time']=[]
EV['ID']['Batt']['SOC']=[]
EV['ID']['Batt']['Size'] = 24

However this didn't allow for the entry of multiple IDs which are in another list admin['ID']. It yielded:

{'ID': defaultdict....,{'Batt':{'SOC:[], 'Size':24, 'Time':[]}}}}

I would appreciate your help!

Upvotes: 2

Views: 244

Answers (2)

Hugh Bothwell
Hugh Bothwell

Reputation: 56634

from collections import defaultdict
import datetime

class ElectricVehicle(object):
    ev_by_id = {}
    ev_by_battery = defaultdict(list)

    @classmethod
    def find(cls, id=None, battery=None):
        if id is not None:
            return [cls.ev_by_id[id]]
        elif battery is not None:
            return cls.ev_by_battery[battery]
        else:
            return []

    def __init__(self, id, battery, states):
        self.id = id
        ElectricVehicle.ev_by_id[id] = self

        self.battery = battery
        ElectricVehicle.ev_by_battery[battery].append(self)

        self.states = list(states)

    def state_at(self, time):
        return self.states[(time.hour*60 + time.minute)/5]

ElectricVehicle(12345, 24, [0.99, 0.99, 0.99])
ElectricVehicle(12346, 30, [0.90, 0.90, 0.89])

evs = ElectricVehicle.find(battery=24)
for ev in evs:
    time = datetime.time(0,3,0)    # 00:03:00
    print("{}: {}".format(ev.id, ev.state_at(time)))

# will print "12345: 0.99"

Upvotes: 3

Max Spencer
Max Spencer

Reputation: 1719

Doing it with objects may be a better option altogether, but that probably depends on the details.. To do this with just lists and dictionaries I would do the following:

Have a dictionary keyed by the IDs of the vehicles with each entry being a dictionary with two entries, battery and charge. The battery entry would just contain the size of the battery as an integer or whatever it needs to be. The charge entry would be a list of the charge readings indexed from 0.

evs = {10001: {battery: 24, charge: [95, 90, ...]}, 11002: { ... }, ...}

Then you can get a battery size of a given EV from its ID:

evs[id]['battery']

Or get the charge reading for a given period for a given ID:

evs[id]['charge'][120] # corresponds to 10:00:00 to 10::05:00

Obviously you could make a nice function to do that time/index translation as some of teh other posters have suggested.

Upvotes: 3

Related Questions