简体   繁体   English

在Python中处理可选值的最佳方法是什么?

[英]What's the best way to handle optional values in Python?

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. 根据可用的数据,我随即填写values But, all the attributes are optional and could be None . 但是,所有属性都是可选的,并且可以为None Ex. 例如 kills could be 12 or None . kills可以是12None 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? 在Python中处理此类可选内容的最佳方法是什么?

Your instincts were right. 你的直觉是对的。 There's no need to store all possible options. 无需存储所有可能的选项。 Just store the ones that are applicable. 只需存储适用的内容即可。

Solution 1: Use get() instead of storing Nones 解决方案1:使用get()而不是存储无

Usually, we don't store all the possible None values in a dictionary. 通常,我们不会将所有可能的None值存储在字典中。 Just fill in the the non-None values and use the dict.get() method for fetch values: 只需填写非None值,然后使用dict.get()方法获取值:

>>> options = {'weapon': 'dagger'}
>>> print(options.get('weapon'))
dagger
>>> print(options.get('food'))
None

Solution 2: Counter defaults to zero for numeric data 解决方案2:数字数据的计数器默认为零

If the values are all numeric, consider using collections.Counter() which lets optional entries default to zero: 如果所有值都是数字,请考虑使用collections.Counter() ,它使可选条目默认为零:

>>> from collections import Counter
>>> options = Counter(kills=4, deaths=2)
>>> options['kills']
4
>>> options['deaths'] += 1
>>> options['deaths']
3
>>> options['assists']
0

Solution 3: getattr() for optional data in instances or classes 解决方案3:getattr()用于实例或类中的可选数据

The getattr() function lets you specific default values for attribute lookup when using instances or classes. 使用实例或类时,使用getattr()函数可以为属性查找提供特定的默认值。 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

Solution 4: For known defaults, use a ChainMap 解决方案4:对于已知的默认设置,请使用ChainMap。

The ChainMap class lets you link pairs of dictionaries together to treat them as a single entity. ChainMap类使您可以将字典对链接在一起,以将它们视为单个实体。

>>> 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. 它还提供了简单的字典访问,因此不需要每次查询都需要get()getattr()

Hope one of these solutions is a good fit for your problem :-) 希望这些解决方案之一适合您的问题:-)

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. 如果您根本不想在需要之前初始化键,则可以使用collections包中的defaultdict快速插入新键,而无需初始设置键值对。

from collections import defaultdict

values = defaultdict(int)

values['seconds'] += 1
values['assists'] += 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM