索引收集数据的Pythonic方法是什么?

时间:2014-12-23 19:38:34

标签: python data-structures collections code-cleanup

我写了一个快速的脚本来搜集关于混合武术战斗及其相关赔率的各种数据。

最初,数据是一个元组,第一个条目是战斗机(字符串)的名称,第二个条目是它们的赔率(浮动)。该脚本稍后访问了此数据,我定义了两个常量FIGHTER = 0ODDS = 1,以便稍后使用fight_data[FIGHTER]fight_data[ODDS]

由于数据是不可变的,因此元组是有意义的,并且通过定义常量,我的理由是我的IDE /编辑器可以捕获拼写错误,而不是使用字典的字符串索引。

FIGHTER = 0
ODDS = 1
fight_data = get_data()

def process_data(fight_data):
    do_something(fight_data[FIGHTER])
    do_something(fight_data[ODDS])

还有哪些替代方案?我想过制作一个FightData类,但数据严格来说是一个带有两个小元素的值对象。

class FightData(object):
    fighter = None
    odds = None
    def __init__(self, fighter, odds):
        self.fighter = fighter
        self.odds = odds

    fight_data = get_data()

    def process_data(data):
        do_something(fight_data.fighter)
        do_something(fight_data.odds)

此外,我意识到我可以使用字典,并且有fight_data["fighter"]但这对我来说似乎既丑陋又不必要。

哪种替代方案最好?

3 个答案:

答案 0 :(得分:1)

Python是一种“多范式”语言,因此在我看来,程序方法或面向对象方法都是有效的和Pythonic。对于这个用例,如果数据量有限,我认为你不必太担心。

但是,如果您要沿着OOP路线前进,我会将您的班级定义为Fighter,并为其提供名为nameodds的属性,然后{{1整个do_something实例:

Fighter

答案 1 :(得分:1)

这些是我的想法......除非你有严重的性能问题或你想要达到的效率指标,否则我会使用dict而不是元组。仅仅因为数据是不可变的并不意味着你必须使用元组。而IMO看起来更干净,更容易阅读。使用像:

这样的幻数
FIGHTER = 1
ODDS = 0

作为索引标记使代码更难理解。一堂课有点矫枉过正。但是,如果您使用dict,您的代码将类似于:

fight_data = get_data()

def process_data(fight_data):
    do_something(fight_data['fighter'])
    do_something(fight_data['odds'])

我刚刚摆脱了两行代码,现在我们不必使用任何魔术变量来引用数据。在不必担心FIGHTER和ODDS的情况下,更容易看到你正在做什么。

如果你真的不需要,不要使用变量。 FIGHTER和ODDS确实没有必要,这就是为什么我们有说法。

答案 2 :(得分:1)

您希望通过字段名称引用的简单不可变数据听起来像是namedtuple的完美用例。

上面链接中的SO问题/答案给出了一个很好的解释,但总结一下:namedpuples很容易定义,内存高效的不可变数据结构,通过属性引用支持数据访问,就像Python类一样,但也完全支持元组操作同样。

from collections import namedtuple

#Defining the form of the namedtuple is much more lightweight than Classes
FightData = namedtuple("FightData", "fighter odds")

#You instantiate a namedtuple much like you would a class instance
fight_data1 = FightData("Andy Hug", 0.8)

#Fields can be referenced by name
print fight_data1.fighter
print fight_data1.odds

#Or by index just like a normal tuple
print fight_data1[0], fight_data1[1]

#They're tuples, so can be iterated over as well
for data in fight_data1:
    print data