from collections import OrderedDict, UserDict, Counter from collections.abc import MutableMapping class MyMutableMapping(MutableMapping): """A fairly pointless class inheriting from MutableMapping""" def __init__(self, data=None): self.data = {} if data is not None: self.data.update(data) def __setitem__(self, key, value): return self.data.__setitem__(key, value) def __getitem__(self, key): return self.data.__getitem__(key) def __delitem__(self, key): return self.data.__delitem__(key) def __iter__(self): return self.data.__iter__() def __len__(self): return self.data.__len__() def __repr__(self): return self.data.__repr__() STRING = 'abbcdb' normal_dict = {char: STRING.index(char) for char in STRING} def pop_item_and_print(string, mapping): print(f'{string: <40}{mapping.popitem()}') # Construct the mappings in exactly the same way (excepting Counter) ordered_dict = OrderedDict(normal_dict) counter = Counter(STRING) mutable_mapping = MyMutableMapping(normal_dict) user_dict = UserDict(normal_dict) # But some use LIFO pop_item_and_print('Standard python dict:', normal_dict) pop_item_and_print('collections.OrderedDict:', ordered_dict) # Counter uses LIFO according to the last key *added* to the dict, # rather than the last time the value associated with that key was added to. pop_item_and_print('collections.Counter (unusual case):', counter) # And some use FIFO pop_item_and_print('collections.abc.MutableMapping:', mutable_mapping) pop_item_and_print('collections.UserDict:', user_dict)