Python организация данных с несколькими словарями - PullRequest
3 голосов
/ 12 ноября 2009

Я пытаюсь создать приложение небольшого типа сервера, и у меня есть вопрос, касающийся организации данных с помощью dicts. Прямо сейчас я группирую данные, используя сокет подключения (главным образом, чтобы проверить, откуда он поступает, и для отправки данных обратно). Как то так: connected[socket] = account_data. По сути, каждый подключенный человек будет иметь данные учетной записи. Поскольку некоторые поля будут часто использоваться для сравнения и проверки информации, например, идентификатора учетной записи, я хочу ускорить процесс с помощью другого диктанта.

Например: чтобы найти accountID с помощью вышеуказанного метода, мне нужно было бы использовать цикл for, чтобы пройти через все доступные соединения в подключенном, посмотреть accountID в account_data для каждого и затем сравнить его. Это, кажется, медленный способ сделать это. Если бы я мог создать dict и использовать accountID в качестве ключа, я думаю, это могло бы немного ускорить процесс. Проблема в том, что я планирую использовать 3 разных диктора, все по-разному. Некоторые данные могут часто меняться, и, кажется, больше хлопот обновлять каждый отдельный раз при изменении информации; есть ли способ связать их вместе?

Возможно, более простой способ объяснить, что я спрашиваю, это: У вас есть Dict A, Dict B, Dict C и Data. Dict A, B и C содержат одинаковые данные. Я хочу, чтобы, если что-то меняется в данных, данные в Dict A, B и C все меняются. Я, конечно, всегда могу сделать dict A = data, dict B = data и т. Д., Но через некоторое время я буду повторять код. Я знаю, что данные устанавливаются после создания dict, поэтому я не совсем уверен, есть ли решение для этого. Я просто ищу совет о том, как лучше организовать данные в этой ситуации.

Ответы [ 4 ]

2 голосов
/ 12 ноября 2009

Во-первых, данные не нужно дублировать. Вы можете иметь 3 словаря, каждый из которых использует свой ключ, но имеет ту же ссылку, что и его значение.

Для этого вам нужно всего лишь один раз изменить объект значения, и это будет отражено во всех словарях (или, точнее, поскольку словари хранят только ссылку, они будут обновлены).

Далее необходимо обеспечить «ссылочную целостность», т. Е. Если конкретная запись удалена, необходимо удалить соответствующую словарную запись во всех 3 словарях, и, если запись будет изменена, словари с ключом, который теперь изменен также необходимо удалить и повторно добавить запись под новым ключом. Это можно сделать с помощью класса, который содержит все 3 словаря и имеет методы Add (), Remove () и (если применимо) Update ().

1 голос
/ 12 ноября 2009

Просто сделайте что-то вроде:

connected[socket] = accountids[account_data.accountid] = account_data

при условии, что account_data является изменяемым объектом с атрибутами, это будет ссылаться на тот же объект как на значение в обоих диктовках, с разными ключами, конечно. не должно иметь , чтобы быть в одном утверждении, т.е.

connected[socket] = account_data
accountids[account_data.accountid] = account_data

множественные присваивания в одном выражении - просто удобство; что заставляет его работать так, как вы хотите, это то, что Python универсально работает с помощью «ссылки на объект» (в присваиваниях, передаче аргументов, операторах возврата и т. д.).

0 голосов
/ 12 ноября 2009

Если у вас есть ссылки на словари, обновление словаря будет отражено для всего со ссылкой.

Клиент подключается и сохраняет розетку, sock. Вы загружаете его аккаунт и втыкаете его в connections[sock]. Затем вы ведете словарь идентификаторов учетных записей (другой способ) со ссылками на учетные записи accounts[account_id]. Давайте попробуем это ...

connected = {}
accounts = {}

def load_account(acct):
    return db_magic(acct)                             # Grab a dictionary from the DB

def somebody_connected(sck, acct):
    global connected, accounts
    account = load_account(acct)
    connected[sck] = account                          # Now we have it by socket
    accounts[acct["accountid"]] = account             # Now we have it by account ID

Поскольку мы присвоили account двум разным местам, любое изменение этого словаря (в любой структуре) будет отражено в другом. Итак ...

def update_username(acct_id, new_username):
    accounts[acct_id]["username"] = new_username

def what_is_my_username(sck):
    sck.send(connected[sck]["username"])              # In response to GIMME_USERNAME

Изменение, которое мы выполняем в update_username, будет автоматически получено, когда мы сделаем sck.send, потому что ссылка точно такая же.

0 голосов
/ 12 ноября 2009

Может быть, один из модулей публикации / подписки для Python может помочь вам здесь? См этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...