LINUX.ORG.RU

Подобрать структуру под данные

 


0

1

Кейс такой - есть цепочка сумматоров, у которого есть номер, к каждому сумматору подключены 1 или 2 микрофона (порт A и B).

Нужно получать данные микрофона как по его номеру, так и обратно - выяснять номер микрофона по известному номеру сумматора и его порту.

MICS = {
    1: {'summator': 8, 'mic': 'B'},
    2: {'summator': 9, 'mic': 'A'},
    3: {'summator': 10, 'mic': 'B'},
    4: {'summator': 10, 'mic': 'A'},
    5: {'summator': 1, 'mic': 'A'},
    6: {'summator': 1, 'mic': 'B'},
    7: {'summator': 2, 'mic': 'A'},
    8: {'summator': 2, 'mic': 'B'},
    ....
}

Мне не кажется что я выбрал не оптимальную структуру словарь в словаре для хранения этого добра. Что посоветуете?

★★★★★

Последнее исправление: Turbid (всего исправлений: 3)

Тебе надо менять данные? По какому параметру нужна оптимизация? Какая версия питона (точная, а не просто 2 или 3)

peregrine ★★★★★
()

А чем список кортежей не подходит?
Для красоты можно всегда завернуть его в какой-нибудь специальный класс или просто написать функцию для раздирания на детали.

Goury ★★★★★
()
Последнее исправление: Goury (всего исправлений: 1)

Если у тебя не тысячи/сотни тысяч/etc элементов, то разницы нет, итерировать это не будет проблемой. Более элегантные решения, скорее всего, будут предполагать подключение сторонних либ (которые не факт, что будут давать прирост в производительности, просто синтаксического сахара подкинут).

evgeny_aa ★★☆
()
Последнее исправление: evgeny_aa (всего исправлений: 1)
mixers = [
    {
        'id': 1,
        'port_A': 1,
        'port_B': 2,
    },
    {
        'id': 2,
        'port_A': 3,
        'port_B': 4,
    },
]


def micFromMixer(mixer, port):
    (result, *_) = filter(lambda x: mixer == x['id'], mixers)
    return result[port]

def mixerByMic(mic):
    (result, *_) = filter(lambda x: mic in (x['port_A'], x['port_B']), mixers)
    return result


micFromMixer(2, 'port_A')  # 3
mixerByMic(4)  # {'id': 2, 'port_A': 3, 'port_B': 4}

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

А если такого микрофона нет, получишь невнятную ValueError: not enough values to unpack

И зачем эти лямбды, если можно [code] def get_mixer_by_mic(mic): for mixer in mixers: if x[‘port_A’] == mic or [‘port_B’] == mic: return mixer [/code]

но я бы вместо этих функций сделал 2 словаря с weakref на объект, а сами объекты положил в список.

pawnhearts ★★★★★
()
Ответ на: комментарий от pawnhearts

Дело не в лямбдах, а в «структуре», для пары десятков сумматоров, кмк, обычного списка миксеров - за глаза.

Это уже ТС пусть сам решает, как ему искать и выбирать, как обрабатывать исключения. У меня просто вариант, не для копипасты.

С обычным списком и 4 функциями, всё это разрулится, без разницы какой сложности будут сами объекты описывающие микрофоны и миксеры.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от peregrine

Тебе надо менять данные?

Нет, возможно потом при рефакторинге эта конфигурация улетит в json

По какому параметру нужна оптимизация?

Оптимизация не принципиальна - всего от 15 до 40 микрофонов

Какая версия питона (точная, а не просто 2 или 3)

3.7-3.8

Turbid ★★★★★
() автор топика
Ответ на: комментарий от Turbid

Голосую за структуру датаклассов, хранимую в tuple

peregrine ★★★★★
()
Ответ на: комментарий от vvn_black

Спасибо, не знал, что конструкции с «*» могут быть слева.

thunar ★★★★★
()
Последнее исправление: thunar (всего исправлений: 3)

Оптимальность по какому критерию? По умолчанию бери наиболее простую и удобную структуру с точки зрения доступа, и ни о чём больше не думай если оно не является боттлнеком по производительности. Возможно самым простым тут будет банальный список с линейным поиском, возможно на единицах десятков элементов он будет и самым быстрым.

И по мне, так словари с фиксированной структурой - это всегда антипаттерн, лучше использовать dataclasses.

slovazap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.