Collections in Python
Collections in Python
In Python we have four different collection or container data types is available like list, tuple, dict, and set. These data types are mostly used to store a collection of data. These are also built-in collections. These built-in collections having separate functionalities.
- list – It is a mutable container datatype and stored different types of elements. It also allows duplicate because it follows index-based storage. Using square brackets []
- dict – It is mutable with key-value pair of storage. It stored the values based on the key. Not using an index. Also not allows duplicate keys. Using curly braces {}
- tuple – It is an immutable container datatype. Also stored different type of elements and allows duplicates because it also follows the index. Using braces ()
- set – It is mutable but it’s a kind of unordered collection it doesn’t follow the index. Duplicates also not allowed.
For the above container data types having some limitations during implementation. For example, dict does not allow duplicate keys. So that python provides some specialized data types to improve the characteristics of these data types using collections module. This module will provide an alternative for container data types.
The following are the specialized data structures to be used in the collections module.
- OrderedDict
- DefaultDict
- Counter
- namedTuple
- deque
- chainMap
- UserDict
- UserList
- UserString
Note: for using this above data structures you need to import collections module
OrderedDict
In this OrderedDict is used to return the same order of dict what we inserted. Simply called ordered collection of elements. Whereas a normal dict object does not follow the order. Here if you change the value of key it doesn’t change the order. It is also a dictionary subclass that remembers the order of the entries which is added.
Example:
from collections import OrderedDict
name=OrderedDict() name[0]='B' name[1]='E' name[2]='S' name[3]='E' name[4]='N' name[5]='T' print("before:",name) name[3]='A' print("After:",name)
In this example we are using the name as the object of OrderedDict it follows the order what we inserted. Even change the value of any given key also it not change the order. For example in this example print the values in before and after change the order is doesn’t change.
Output:
before: OrderedDict([(0, 'B'), (1, 'E'), (2, 'S'), (3, 'E'), (4, 'N'), (5, 'T')]) After: OrderedDict([(0, 'B'), (1, 'E'), (2, 'S'), (3, 'A'), (4, 'N'), (5, 'T')])
DefaultDict:
DefaultDict is used to create a dict with duplicate keys. It is also a subclass of dictionary using factory function to find missing values. It is not like dict class because in normal dict class not allows using duplicate keys. If we try to use duplicate keys it will take the last value of the particular key. To overcome this limitation we can use DefaultDict.
Example:
from collections import defaultdict
marks = [ ('Anbu', 90), ('Anand', 95), ('Anbu', 99), ('Balu', 98)] dict_marks = defaultdict(list) for k, v in marks: dict_marks[k].append(v) print(list(dict_marks.items()))
In this Example defaultdict using the list to add the dict. Here we are able to add two values to the same key. The key (‘Anbu’) will have two times. whereas dict is not allowed this.
Output:
[('Anbu', [90, 99]), ('Balu', [98]), ('Anand', [95])]
Counter:
The counter is used to count the hashtable elements. It is also used to count the items entered in the collection of a particular key. It is also a subclass of the dictionary to count items.
It also performs some additional operations.
- element function – It returns the all elements of the counter in a list.
- Most_common() – It returns the count of each element in the counter assorted list.
- Subtract() – It acquiring an Iterable Object as a parameter and subtract the count of the elements in the available counter.
Example:
from collections import Counter marks = [ ('Anbu', 90), ('Anand', 95), ('Anbu', 99), ('Balu', 98)] count_marks = Counter(name for name, marks in marks) print(count_marks)
In This Example, we have the duplicate key and it will take as an element. So that the counter will count the entries of each key within the list and returns count of each key.
Output:
Counter({'Anbu': 2, 'Balu': 1, 'Anand': 1})
Example:
from collections import Counter marks=[10,10,20,30,50,50,10,30,40,10] print(Counter(marks))
In this Example, the counter will just count the elements which entered in no.of times based on that it will arrange elements also.
Output:
Counter({10: 4, 50: 2, 30: 2, 40: 1, 20: 1})
namedtuple():
It is also a tuple but comes with named entry. That means every element of the tuples are stored using a name like a key. In this named tuple no need to use index values to get elements just using the name. It is easier than using an index because we no need to remember the index values.
Example:
import collections Emp = collections.namedtuple('Emp', 'name year dept') besant = Emp(name='Besant', year=12, dept='Training') print(besant) print('Name of User: {0}'.format(besant.name))
In This Example, we use the Emp as the tuple but we declared emp as namedtuple it consists of an object with keys that means name for each element. For this, we can add any no.of elements to a particular object.
Output:
Emp(name='Besant', year=12, dept='Training') Name of User: Besant
deque:
Deque is normally representing a double-ended queue. That is we can able to adding and removing elements in both the right and left side. It is also a kind of list used to inserting and deleting easily. It is the enhancement of a queue or stack.
Example:
import collections name = collections.deque('Besant') print('Deque :', name) print('Queue Length:', len(name)) print('Left part :', name[0]) print('Right part :', name[-1])
In this example, we implement the deque process with one string of values. It can able to get the element in both ends.
Output:
Deque : deque(['B', 'e', 's', 'a', 'n', 't']) Queue Length: 6 Left part : B Right part : t
Example:
import collections str = collections.deque('Besant') print('Deque :', str) str.extendleft('...') str.append('-') print('Deque :', str) str.remove('a') print('remove(a):', str)
In the same example now we implement the insertion of the element. Here add the values in both ends using the predefined methods like append() and extendLeft(). Also we remove the values using remove().
Output:
Deque :deque(['B', 'e', 's', 'a', 'n', 't']) Deque :deque(['.', '.', '.', 'B', 'e', 's', 'a', 'n', 't', '-']) remove(a):deque(['.', '.', '.', 'B', 'e', 's', 'n', 't', '-'])
ChainMap:
It is a kind of dictionary class used to view multiple mappings with a single unit. It just like encapsulation in oops. Because it is also mappings the more than one dictionaries.
If you have more than one dictionaries in several keys it to be viewed in a single list with both dictionaries.
Example:
from collections import ChainMap a = { 1: 'besant' , 2: 'java'} b = {3: 'Python' , 4: 'Data Science'} c = ChainMap(a,b) print(c)
In this above example, we are having two dictionaries with having four key-value pairs it will be viewed in a single list with added in the ChainMap called c. when I going to list keys of dictionaries just print the c.
Output:
ChainMap({1: 'besant', 2: 'java'}, {3: 'Python', 4: 'Data Science'})
It is also possible to add and reverse the more than one dictionaries in the previously created ChainMap.
Example:
a1 = { 5: 'Machine Learning' , 6: 'cloud computing'} c1 = c.new_child(a1) print(c1)
In this example, we are adding the new dict with already created chain map using the new_child() method.
Output:
ChainMap({5: ‘Machine Learning’, 6: ‘cloud computing’}, {1: ‘besant’, 2: ‘java’}, {3: ‘Python’, 4: ‘Data Science’})
UserDict:
This class acts as a wrapper for the dictionary class. It becomes easy to work with this class for the dictionary because it will take a dictionary to become an attribute. Here the dictionary object is accessed using data attribute.
Example:
from collections import UserDict mobiles = UserDict({'a':'apple','r': 'redmi', 'h': 'honor', 's': 'samsung'}) print(mobiles.data)
In this example, we are using the UserDict to store the elements like dict. For this we are not using any methods like items(),keys() and values() to get the elements. Simple use the data attribute to receive the values as Dict.
Output:
{'s': 'samsung', 'r': 'redmi', 'h': 'honor', 'a': 'apple'}
UserList:
This class acts as a wrapper class for list elements. It also uses the attribute to take the values of list like userdict from the dictionary. It is also used as a base class for different list classes and inherits. Also overrides the methods and new one as well.
Example:
from collections import UserList students = UserList({'student_one': 'Too good', 'score': 499}) print(students.data)
In this example, we using the user list with dictionary values and use the data attribute to get the keys as list.
Output:
['score', 'student_one']
UserString:
This class also acts as a wrapper for the string elements. It also used to manipulate the string values. Because normal string is not allowing any manipulation like adding and removing. Here we are having two classes UserString and MutableString. In this MutableString not used most. Because its mostly in slicing process. UserString is most used one for manipulation of String objects.
Example:
from collections import UserString class MyName(UserString): def append_str(self, str): self.datastr = self.datastr + str def insert_str(self, index, str): self.datastr = self.datastr[index:] + str + self.datastr[index:] def remove_str(self, str): self.datastr = self.datastr.replace(str, "") text='robin gannet hello' names = MyName(text) for b in ["gannet", "robin", "nuthatch"]: names.remove_str(b) print(names)
In this example, we inherit the UserString to the class and write some own methods for manipulating the String values like append, insert and remove. This is the use of UserString.