Add object to start of dictionary

33.3k views Asked by At

I am making a group chatting app and I have images associated with the users, so whenever they say something, their image is displayed next to it. I wrote the server in python and the client will be an iOS app. I use a dictionary to store all of the message/image pairs. Whenever my iOS app sends a command to the server (msg:<message), the dictionary adds the image and message to the dictionary like so:dictionary[message] = imageName, which is converted to lists then strings to be sent off in a socket. I would like to add the incoming messages to the start of the dictionary, instead of the end. Something like

#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}

Is there any way to add the object to the start of the dictionary?

7

There are 7 answers

0
Mazdak On BEST ANSWER

First of all it doesn't added the item at the end of dictionary because dictionaries use hash-table to storing their elements and are unordered. if you want to preserve the order you can use collections.OrderedDict.but it will appends the item at the end of your dictionary. One way is appending that item to the fist of your items then convert it to an 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')])

Also as another efficient way if it's not necessary to use a dictionary you can use a deque that allows you to append from both side :

>>> 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')])
0
poros On

I am not sure that a dictionary is the best data structure for your data, but you may find useful collections.OderedDict. It is basically a dictionary that remembers the order of keys added to the dictionary in a FIFO fashion (which is the opposite of what you need).

If you want to retrieve all your items starting from the most recent one, you can use reversed() to reverse dictionary iterators. You can also use the method popitem() to retrieve (and remove) from the dictionary the key-value pair you last entered.

Link to the docs: https://docs.python.org/2/library/collections.html#collections.OrderedDict

0
Chris Johnson On

As others have pointed out, there is no concept of "order" in a standard dict. Although you can use an OrderedDict to add ordering behavior, this brings other considerations -- unlike a normal dict, isn't a portable data structure (e.g. dumping to JSON then reloading does not preserve order) -- and isn't available in the standard library for all versions of Python.

You might be better off using a sequential key in a standard dict -- a count-up index, or time stamp -- to keep things simple.

3
dev J On

(python3) good example from Manjeet on 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}
0
drakon On

With python 3.9+ (PEP 584) there's an even nicer solution with the | operator.

old_dictionary = {"hello": "image3.png"}
new_dictionary = {"i like py": "image1.png"} | old_dictionary
1
Tomiwa On

As others have pointed out, there is no "order" in a dictionary. However, if you are like me and just need a temporary (/ hacky) workaround that works for your purposes. There is a way to do this.

You can iterate the dictionary, and append the item at the beginning of the iteration process. This seemed to work for me.

The relevant part is where new_fields is declared. I am including the rest for context.

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)

1
Craig Anderson On

For the use case described it sounds like a list of tuples would be a better data structure.

However, it has been possible to order a dictionary since Python 3.7. Dictionaries are now ordered by insertion order.

To add an element anywhere other than the end of a dictionary, you need to re-create the dictionary and insert the elements in order. This is pretty simple if you want to add an entry to the start of the dictionary.

# 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'}