2014-12-23 2 views
-2

Я написал быстрый скрипт, чтобы очистить различные данные о битвах с единоборствами и их связанных шансах.Каков самый Pythonic способ индексирования данных коллекции

Первоначально данные были кортежем, причем первая запись была именем истребителя (строки), а вторая была их коэффициентом (float). Скрипт позже получил доступ к этим данным, и я определил две константы: FIGHTER = 0 и ODDS = 1, чтобы позднее использовать fight_data[FIGHTER] или fight_data[ODDS].

Поскольку данные неизменяемы, кортеж имел смысл, и, определяя константы, мои рассуждения состояли в том, что мой IDE/Editor мог улавливать опечатки, а не использовать индекс строки для словаря.

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"] но кажется, что как некрасиво и ненужно мне.

Какой из этих альтернатив является лучшим?

+0

Это вопрос SO-актуальный или запрос кодового обзора? – J0e3gan

+0

Просьба не запрашивать код, просто вопрос с точки зрения стиля. –

+0

Это будет запрос IMO об обзоре кода. – J0e3gan

ответ

1

Python - это «язык с несколькими парадигмами», поэтому, на мой взгляд, действительный и объектно-ориентированный подход действителен и Pythonic. Для этого прецедента, с таким ограниченным объемом данных, я не думаю, что вам нужно слишком беспокоиться.

Однако, если вы собираетесь вниз маршрут ООП, я бы определить свой класс, чтобы называться Fighter и дать ему атрибуты называются name и odds, а затем 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) 
+0

* Должен быть один - и желательно только один - простой способ сделать это. * - [PEP 20: Zen of Python] (https://www.python.org/dev/peps/pep- 0020 /) (ака 'import this') – Palec

1

Это мои мысли ... если у вас нет серьезных проблем с производительностью или показателей эффективности, которые вы пытаетесь достичь, я бы использовал вместо dict вместо dict. Просто потому, что данные неизменяемы, не означает, что вам нужно использовать кортеж. И ИМО выглядит чище и легче читать. Использование магических чисел, таких как:

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.

1

Простые части непреложных данных, которые вы хотите ссылаться по имени поля, звучат как идеальный вариант для namedtuple.

Вопрос и ответ SO в приведенной выше ссылке дает отличное объяснение, но в итоге: 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 
Смежные вопросы