【问题标题】:What is the most Pythonic way to index collection data索引集合数据的最 Pythonic 方式是什么
【发布时间】:2015-02-21 23:35:51
【问题描述】:

我编写了一个快速脚本来收集有关综合格斗比赛及其相关赔率的各种数据。

最初,数据是一个元组,第一个条目是战斗机的名称(字符串),第二个条目是他们的赔率(浮点数)。脚本稍后访问了这些数据,我定义了两个常量,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"],但这对我来说既丑陋又不必要。

这些替代方案中哪一个是最好的?

【问题讨论】:

  • 这是一个非常热门的问题还是代码审查请求?
  • 不要求代码审查,只是风格方面的问题。
  • 这将是 IMO 的代码审查请求。
  • @ViktorChynarov 你有代码给我们看吗?您是否遇到任何性能问题?我真的不知道如何解决这个问题。
  • “Pythonic”——语言和概念上的失望。 (即“我担心我不够 Pythonic。”)以前这个概念只是被称为“惯用的”——并没有那么充满 Pythonic 的自我意识。 :)

标签: python data-structures collections code-cleanup


【解决方案1】:

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

但是,如果您要走 OOP 路线,我会将您的类定义为 Fighter,并为其赋予名为 nameodds 的属性,然后将 do_something 与整个 Fighter实例:

class Fighter(object):
    def __init__(self, name, odds):
        self.name = name
        self.odds = odds

fighters = get_data()

# for example:
for fighter in fighters:
     do_something(fighter)

【讨论】:

【解决方案2】:

这些是我的想法...除非您遇到严重的性能问题或要达到的效率指标,否则我会使用字典而不是元组。仅仅因为数据是不可变的并不意味着您必须使用元组。而且 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 真的没有必要,这就是我们有 dicts 的原因。

【讨论】:

    【解决方案3】:

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

    上面链接中的 SO question/answer 给出了很好的解释,但总而言之:namedtuples 是易于定义的、内存高效的不可变数据结构,它支持通过属性引用进行数据访问,就像 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
    

    【讨论】:

      猜你喜欢
      • 2016-02-29
      • 2015-11-29
      • 1970-01-01
      • 2017-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多