{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#Collections Module\n", "\n", "The collections module is a built-in module that implements specialized container data types providing alternatives to Python’s general purpose built-in containers. We've already gone over the basics: dict, list, set, and tuple.\n", "\n", "Now we'll learn about the alternatives that the collections module provides.\n", "\n", "##Counter\n", "\n", "*Counter* is a *dict* subclass which helps count hash-able objects. Inside of it elements are stored as dictionary keys and the counts of the objects are stored as the value.\n", "\n", "Lets see how it can be used:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from collections import Counter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Counter() with lists**" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Counter({1: 6, 2: 6, 3: 4, 32: 1, 12: 1, 21: 1, 223: 1})" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "l = [1,2,2,2,2,3,3,3,1,2,1,12,3,2,32,1,21,1,223,1]\n", "\n", "Counter(l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Counter with strings**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Counter({'b': 7, 's': 6, 'h': 3, 'a': 2})" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Counter('aabsbsbsbhshhbbsbs')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Counter with words in a sentence**" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Counter({'word': 3, 'each': 3, 'times': 2, 'show': 1, 'this': 1, 'many': 1, 'in': 1, 'up': 1, 'How': 1, 'does': 1, 'sentence': 1})" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'How many times does each word show up in this sentence word times each each word'\n", "\n", "words = s.split()\n", "\n", "Counter(words)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[('word', 3), ('each', 3)]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Methods with Counter()\n", "c = Counter(words)\n", "\n", "c.most_common(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##Common patterns when using the Counter() object" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sum(c.values()) # total of all counts\n", "c.clear() # reset all counts\n", "list(c) # list unique elements\n", "set(c) # convert to a set\n", "dict(c) # convert to a regular dictionary\n", "c.items() # convert to a list of (elem, cnt) pairs\n", "Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs\n", "c.most_common()[:-n-1:-1] # n least common elements\n", "c += Counter() # remove zero and negative counts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##defaultdict\n", "\n", "defaultdict is a dictionary like object which provides all methods provided by dictionary but takes first argument (default_factory) as default data type for the dictionary. Using defaultdict is faster than doing the same using dict.set_default method.\n", "\n", "**A defaultdict will never raise a KeyError. Any key that does not exist gets the value returned by the default factory.**" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from collections import defaultdict" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d = {}" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "ename": "KeyError", "evalue": "'one'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'one'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'one'" ] } ], "source": [ "d['one'] " ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d = defaultdict(object)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['one'] " ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one\n" ] } ], "source": [ "for item in d:\n", " print item" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can also initialize with default values:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "d = defaultdict(lambda: 0)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['one']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##OrderedDict\n", "An OrderedDict is a dictionary subclass that remembers the order in which its contents are added.\n", "\n", "Fro example a normal dictionary:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Normal dictionary:\n", "a A\n", "c C\n", "b B\n", "e E\n", "d D\n" ] } ], "source": [ "print 'Normal dictionary:'\n", "\n", "d = {}\n", "\n", "d['a'] = 'A'\n", "d['b'] = 'B'\n", "d['c'] = 'C'\n", "d['d'] = 'D'\n", "d['e'] = 'E'\n", "\n", "for k, v in d.items():\n", " print k, v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An Ordered Dictionary:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OrderedDict:\n", "a A\n", "b B\n", "c C\n", "d D\n", "e E\n" ] } ], "source": [ "print 'OrderedDict:'\n", "\n", "d = collections.OrderedDict()\n", "\n", "d['a'] = 'A'\n", "d['b'] = 'B'\n", "d['c'] = 'C'\n", "d['d'] = 'D'\n", "d['e'] = 'E'\n", "\n", "for k, v in d.items():\n", " print k, v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##Equality with an Ordered Dictionary\n", "A regular dict looks at its contents when testing for equality. An OrderedDict also considers the order the items were added.\n", "\n", "A normal Dictionary:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dictionaries are equal? \n", "True\n" ] } ], "source": [ "print 'Dictionaries are equal? '\n", "\n", "d1 = {}\n", "d1['a'] = 'A'\n", "d1['b'] = 'B'\n", "\n", "d2 = {}\n", "d2['b'] = 'B'\n", "d2['a'] = 'A'\n", "\n", "print d1 == d2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An Ordered Dictionary:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dictionaries are equal? \n", "False\n" ] } ], "source": [ "print 'Dictionaries are equal? '\n", "\n", "d1 = collections.OrderedDict()\n", "d1['a'] = 'A'\n", "d1['b'] = 'B'\n", "\n", "\n", "d2 = collections.OrderedDict()\n", "\n", "d2['b'] = 'B'\n", "d2['a'] = 'A'\n", "\n", "print d1 == d2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#namedtuple\n", "The standard tuple uses numerical indexes to access its members, for example:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "t = (12,13,14)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For simple use cases, this is usually enough. On the other hand, remembering which index should be used for each value can lead to errors, especially if the tuple has a lot of fields and is constructed far from where it is used. A namedtuple assigns names, as well as the numerical index, to each member. \n", "\n", "Each kind of namedtuple is represented by its own class, created by using the namedtuple() factory function. The arguments are the name of the new class and a string containing the names of the elements.\n", "\n", "You can basically think of namedtuples as a very quick way of creating a new object/class type with some attribute fields.\n", "For example:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from collections import namedtuple" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Dog = namedtuple('Dog','age breed name')\n", "\n", "sam = Dog(age=2,breed='Lab',name='Sammy')\n", "\n", "frank = Dog(age=2,breed='Shepard',name=\"Frankie\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We construct the namedtuple by first passing the object type name (Dog) and then passing a string with the variety of fields as a string with spaces between the field names. We can then call on the various attributes:" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Dog(age=2, breed='Lab', name='Sammy')" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sam" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sam.age" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'Lab'" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sam.breed" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sam[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##Conclusion\n", "\n", "Hopefully you now see how incredibly useful the collections module is in Python and it should be your go-to module for a variety of common tasks!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }