Reputation: 263
I have a data structure below which I use to keep track of certain data from a video game.
values = {
'kills': None,
'assists': None,
'deaths': None,
'minutes': None,
'seconds': None,
}
Depending on what data I have available I fill up the values
as I go. But, all the attributes are optional and could be None
. Ex. kills
could be 12
or None
. It all depends on what data I had available in that moment. I could make this a bit better by having an object to store the data, but I'll still have the issue of these optional values.
What's the best way to deal with optionals like this in Python?
Upvotes: 1
Views: 10932
Reputation: 226694
Your instincts were right. There's no need to store all possible options. Just store the ones that are applicable.
Usually, we don't store all the possible None values in a dictionary. Just fill in the the non-None values and use the dict.get() method for fetch values:
>>> options = {'weapon': 'dagger'}
>>> print(options.get('weapon'))
dagger
>>> print(options.get('food'))
None
If the values are all numeric, consider using collections.Counter() which lets optional entries default to zero:
>>> from collections import Counter
>>> options = Counter(kills=4, deaths=2)
>>> options['kills']
4
>>> options['deaths'] += 1
>>> options['deaths']
3
>>> options['assists']
0
The getattr() function lets you specific default values for attribute lookup when using instances or classes. The instance approach is especially helpful for tracking data for each player:
>>> anka = Player()
>>> vlad = Player()
>>> anka.hits = 5
>>> vlad.assists = 2
>>> print(getattr(anka, 'hits', None))
5
>>> print(getattr(vlad, 'hits', None))
None
The ChainMap class lets you link pairs of dictionaries together to treat them as a single entity.
>>> from collections import ChainMap
>>> defaults = ChainMap(dict(kills=0, assists=0, location='start', status='alive'))
>>> anka = defaults.new_child()
>>> vlad = defaults.new_child()
>>> anka['hits'] = 5
>>> vlad['assists'] = 2
>>> anka['hits']
5
>>> vlad['location']
'start'
This last solution lets you organize all possible defaults in one place, while letting instances store only the data that is needed. It also provids simple dictionary access so there is no need for get() or getattr() for every lookup.
Hope one of these solutions is a good fit for your problem :-)
Upvotes: 4
Reputation: 181
If you simply never want to initialize the keys until you have to, you can use defaultdict from the collections package to insert new keys on the fly without the need of initially setting the key value pair.
from collections import defaultdict
values = defaultdict(int)
values['seconds'] += 1
values['assists'] += 1
Upvotes: 0