Python Tips 6 - Collections : Container Datatype

in STEMGeeks4 years ago

Python Tips - Collections : Container Datatype

source: geeksforgeeks.org

We all know the common container types in python tuple, dict, list, set but ... There is more.

The module collections expose the types :

  • Counter: (dict subclass for counting hashable objects)
  • ChainMap: (dict-like class for creating a single view of multiple mappings)
  • deque: (list-like container with fast appends and pops on either end)
  • OrderedDict: (dict subclass that remembers the order entries were added)
  • UserList: (wrapper around list objects for easier list subclassing)
  • UserDict: (wrapper around dictionary objects for easier dict subclassing)
  • UserString: (wrapper around string objects for easier string subclassing)

In this article, we will take look at all of thoses datatypes (except the User* wrapper, they are fairly easy to use).

Let's do it

>>>from collections import Counter, deque, ChainMap, OrderedDict 

Counter

It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. The Counter class is similar to bags or multisets in other languages.

>>>c = Counter()                           # a new, empty counter
>>>c = Counter('test1')                    # a new counter from an iterable
>>>c = Counter({'ball': 4, 'blue': 2})     # a new counter from a mapping
>>>c = Counter(apples=4, strawberries=8)   # a new counter from keyword args

Counter objects have a dictionary interface except that they return a zero count for missing items instead of raising a KeyError:

>>>counter_instance = Counter(['eggs', 'ham'])
>>>counter_instance['bacon']       # count of a missing element is zero
0

Using Counter class to create lists:

>>>counter_instance = Counter(a=4, b=2, c=0, d=-2)
>>>sorted(counter_instance.elements())
['a', 'a', 'a', 'a', 'b', 'b']

Counter class have a usefull method substract:

>>>counter_instance = Counter(a=4, b=2, c=0, d=-2)
>>>d = Counter(a=1, b=2, c=3, d=4)
>>>counter_instance.subtract(d)
>>>counter_instance
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

There is a lot more, but not that usefull, find it here

ChainMap

A ChainMap groups multiple dicts or other mappings together to create a single, updateable view. If no maps are specified, a single empty dictionary is provided so that a new chain always has at least one mapping.

>>> baseline = {'music': 'bach', 'art': 'rembrandt'}
>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
>>> ChainMap(adjustments, baseline)
ChainMap({'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'})
>>> ChainMap(adjustments, baseline).maps
[{'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'}]

If you want to add a new dictionary to an existing ChainMap, use new_child() method. It creates a new ChainMap with the newly added dictionary.

>>>chain = ChainMap({'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'})
>>>new_chain_map = chain.new_child({'chef': 'escachet'})
ChainMap({'chef': 'escachet'}, {'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'})

Well what is the point?

You can use a ChainMap instance just like a regular dict...
Think about it, you can use ChainMaps like a dict, while maintaining the chain architecture.

ex:

>>>chain = ChainMap({'art': 'van gogh', 'opera': 'carmen'}, {'music': 'bach', 'art': 'rembrandt'})
>>>chain_map['music']
'bach'
>>>list(chain.keys())
['music', 'opera', 'art']
>>>list(chain.values())
['bach', 'carmen', 'van gogh']
>>list(chain.items())
[('art', 'van gogh'), ('music', 'bach'), ('opera', 'carmen')]

OrderedDict

OrderedDict is a dictionary where keys maintain the order in which they are inserted, which means if you change the value of a key later, it will not change the position of the key.

>>>od = OrderedDict()
>>>od['a'] = 1
>>>od['b'] = 2
>>>od['c'] = 3
>>od
OrderedDict([('a', 1), ('b', 2), ('c', 3)])

You can use the regular dict methods like items(), keys() or values().

What can we do with it?

We can use the Counter and OrderedDict in the same script.

>>>list = ["a","c","c","a","b","a","a","b","c"]
>>>cnt = Counter(list)
>>>od = OrderedDict(cnt.most_common())
>>>for key, value in od.items():
>>>    print(key, value)
a 4
c 3
b 2

This class is widely used, you can see it for yourself here!

deque

The deque is a list optimized for inserting and removing items. That's it, it's just a fast list in the end.

>>>list = ["a","b","c"]
>>>deq = deque(list)
>>>print(deq)
deque(['a', 'b', 'c'])

The main difference is that the deque class has a method called appendleft wich is the high performance equivalent to list.insert(0,value).

You made it to the end, bravo! If you have any questions, don't forget to ask. See you next time! If you spot a grammar or vocabulary mistake, please let me know in the comments.

You will be able to find a good part of the articles in this account in this repository.

To go directly to the section you are currently viewing click here.

Latest article in the series Python Tips: Python Tips 5 - Webbrowser package

Sort:  

You earlier said that what you publish does not relate to what we want in our community but the fact is it is exactly what we appreciate. A cross post will also be will appreciated. Great post

Thanks for sharing

Your post has been submitted to be manually curated by @gitplait community account because this is the kind of publications we like to see in our community.

Join our Community on Hive and Chat with us on Discord.

[Gitplait-Team]

Didn't know about this before @slashformotion! Interesting, would be useful for complex solutions.

I'm confused with Counter:

>>>counter_instance = Counter(a=4, b=2, c=0, d=-2)
>>>sorted(counter_instance.elements())
['a', 'a', 'a', 'a', 'b', 'b']

Is the value part the occurence or the index? I see the sorted output of the elements() function is only displaying a list of letter with key/index greater than 0.

It's not exactly that.

value is a key and the count is the value in Counter. Counter is a kind of dict, if that help you visualize.

if you want to see how it's done => https://github.com/python/cpython/blob/c77f71f9819022fa3adeb2f710e564a392ff24c6/Lib/collections/init.py#L489