Добавить объект в начало словаря

Я делаю приложение для группового чата, и у меня есть изображения, связанные с пользователями, поэтому всякий раз, когда они что-то говорят, их изображение отображается рядом с ним. Я написал сервер на питоне, а клиент будет приложением для iOS. Я использую словарь для хранения всех пар сообщение/изображение. Всякий раз, когда мое приложение для iOS отправляет команду на сервер (msg:<message), словарь добавляет изображение и сообщение в словарь, например так: dictionary[message] = imageName, который преобразуется в списки, а затем строки для отправки в сокет. Я хотел бы добавить входящие сообщения в начало словаря, а не в конец. Что-то типа

#When added to end:
dictionary = {"hello":image3.png}
#new message
dictionary = {"hello":image3.png, "i like py":image1.png}

#When added to start:
dictionary = {"hello":image3.png}
#new message
dictionary = {"i like py":image1.png, "hello":image3.png}

Есть ли способ добавить объект в начало словаря?


person Minebomber    schedule 21.06.2015    source источник
comment
Словарь (если мы говорим о стандартном словаре Python) не имеет порядка.   -  person Ashalynd    schedule 21.06.2015
comment
Словари не отсортированы. Это означает, что вы не можете добавлять/добавлять к нему элемент. Вместо этого вы можете использовать список, где у вас будет [ ("hello","image3.png") ], затем вы можете использовать yourList.insert(0, ("i like py":"image1.png")), который вставит сообщение как первый (индекс 0) элемент   -  person kecer    schedule 21.06.2015
comment
Этот вопрос немного отличается от дублированного!   -  person kasravnd    schedule 21.06.2015
comment
Я на самом деле не думал об этом. Я решил использовать списки, потому что мои навыки Python немного заржавели.   -  person Minebomber    schedule 21.06.2015
comment
Реализации словаря Python заказывались уже много лет, хотя это была деталь реализации. Начиная с версии 3.7, для поддержания порядка требуется язык.   -  person Craig.Feied    schedule 15.01.2021


Ответы (6)


Прежде всего, он не добавляет элемент в конец словаря, потому что словари используют хэш-таблицу для хранения своих элементов и неупорядочены. если вы хотите сохранить порядок, вы можете использовать collections.OrderedDict, но он добавит элемент в конец вашего словаря. Один из способов — добавить этот элемент в список ваших элементов, а затем преобразовать его в Orderd:

>>> from collections import OrderedDict
>>> d=OrderedDict()
>>> for i,j in [(1,'a'),(2,'b')]:
...    d[i]=j
... 
>>> d
OrderedDict([(1, 'a'), (2, 'b')])
>>> d=OrderedDict([(3,'t')]+d.items())
>>> d
OrderedDict([(3, 't'), (1, 'a'), (2, 'b')])

Также в качестве еще одного эффективного способа, если нет необходимости использовать словарь, вы можете использовать deque, который позволяет добавлять с обеих сторон:

>>> from collections import deque
>>> d=deque()
>>> d.append((1,'a'))
>>> d.append((4,'t'))
>>> d
deque([(1, 'a'), (4, 't')])
>>> d.appendleft((8,'p'))
>>> d
deque([(8, 'p'), (1, 'a'), (4, 't')])
person kasravnd    schedule 21.06.2015

Для описанного варианта использования список кортежей был бы лучшей структурой данных.

Однако, начиная с Python 3.7, можно было заказать словарь. Словари теперь упорядочены по порядку вставки.

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

# Existing data structure
old_dictionary = {"hello": "image3.png"}

# Create a new dictionary with "I like py" at the start, then
# everything from the old data structure.
new_dictionary = {"i like py": "image1.png"}
new_dictionary.update(old_dictionary)

# new_dictionary is now:
# {'i like py': 'image1.png', 'hello': 'image3.png'}
person Craig Anderson    schedule 19.08.2020
comment
Это правильный ответ. В то время как словарь неупорядочен, когда мы обрабатываем некоторые данные, записанные из словаря, существует порядок. Этот ответ гарантирует, что мы можем добавить эти данные. Я специально думаю о JsonLines. - person Jiulin Teng; 07.03.2021

(python3) хороший пример от Manjeet на geeksforgeeks.org

test_dict = {"Gfg" : 5, "is" : 3, "best" : 10}  
updict = {"pre1" : 4, "pre2" : 8}

# ** operator for packing and unpacking items in order
res = {**updict, **test_dict}
person dev J    schedule 08.05.2021

Я не уверен, что словарь — лучшая структура данных для ваших данных, но вы можете найти полезное collections.OderedDict. По сути, это словарь, который запоминает порядок добавления ключей в словарь в порядке FIFO (что противоположно тому, что вам нужно).

Если вы хотите получить все свои элементы, начиная с самого последнего, вы можете использовать reversed() для реверсирования итераторов словаря. Вы также можете использовать метод popitem() для извлечения (и удаления) из словаря последней введенной пары ключ-значение.

Ссылка на документы: https://docs.python.org/2/library/collections.html#collections.OrderedDict

person poros    schedule 21.06.2015

Как указывали другие, в стандартном словаре нет понятия «порядок». Хотя вы можете использовать OrderedDict для добавления поведения упорядочивания, это приводит к другим соображениям - в отличие от обычного dict, не является переносимой структурой данных (например, дамп в JSON, а затем перезагрузка не сохраняет порядок) - и недоступен в стандартная библиотека для всех версий Python.

Возможно, вам лучше использовать последовательный ключ в стандартном словаре — счетный индекс или отметку времени — для простоты.

person Chris Johnson    schedule 21.06.2015

Как указывали другие, в словаре нет «порядка». Однако, если вы похожи на меня и вам просто нужен временный (/хакерский) обходной путь, который работает для ваших целей. Есть способ сделать это.

Вы можете повторить словарь и добавить элемент в начале процесса итерации. Это, казалось, сработало для меня.

Соответствующая часть находится там, где объявлено new_fields. Я включаю остальное для контекста.

userprofile_json = Path(__file__).parents[2] / f"data/seed-data/user-profile.json"

    with open(userprofile_json) as f:
        user_profiles = json.load(f)

    for user_profile in user_profiles:

        new_fields = {
            'user':  user_profile['fields']['username'],
        }
        for k, v in user_profile['fields'].items():
            new_fields[k] = v

        user_profile['fields'] = new_fields


    with open(userprofile_json, 'w') as f:
        json.dump(user_profiles, f, indent=4)

person Tomiwa    schedule 31.05.2020