From fc2497f32a37534ed1c95fe4a19481aab19d8973 Mon Sep 17 00:00:00 2001 From: Duroktar Date: Mon, 10 Apr 2017 15:37:30 -0300 Subject: [PATCH] Update compress challenge with itertools.groupby() code --- .../compress/compress_solution.ipynb | 79 +++++++++++++++---- arrays_strings/compress/test_compress.py | 4 +- 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/arrays_strings/compress/compress_solution.ipynb b/arrays_strings/compress/compress_solution.ipynb index fbceb59..ad59c08 100644 --- a/arrays_strings/compress/compress_solution.ipynb +++ b/arrays_strings/compress/compress_solution.ipynb @@ -92,9 +92,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "class CompressString(object):\n", @@ -119,6 +117,49 @@ " return prev_char + (str(count) if count > 1 else '')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm 2\n", + "\n", + "Using itertools.groupby()\n", + "\n", + "- Get groups of letters and their counts. ex: \"AAABCC\" -> ([\"A\", 3], [\"B\", 1], [\"C\", 2])\n", + " - This works because itertools.groupby() returns an iterator of 2-tuples, the first item of the tuple is the current character and the second is an iterator over each occurence of said character. So we unpack each 2-tuple group using a comprehension and build it anew, this time replacing the second item of the tuple with the length of the list of occurences, giving us a result like that shown in the example above.\n", + "- Using string formatting inside a comprehension, we replace any count less than 2 with an empty string, effectively ignoring the 1's. The result is then string joined.\n", + "- Return our result if the length of the compressed string is less than the length of the original, otherwise return the original." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import itertools\n", + "\n", + "\n", + "class CompressString_2(object):\n", + "\n", + " def compress_2(self, string):\n", + " if string is None:\n", + " return\n", + "\n", + " groups = ([letter, len(list(group))] for letter, group in itertools.groupby(string))\n", + " result = \"\".join(\"%s%s\" % (letter, count if count > 1 else '') for letter, count in groups)\n", + " return result if len(result) < len(string) else string" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -128,10 +169,8 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, + "execution_count": 23, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -155,13 +194,15 @@ " assert_equal(func('AAABCCDDDDE'), 'A3BC2D4E')\n", " assert_equal(func('BAAACCDDDD'), 'BA3C2D4')\n", " assert_equal(func('AAABAACCDDDD'), 'A3BA2C2D4')\n", - " print('Success: test_compress')\n", + " print('Success: %s' % func.__name__)\n", "\n", "\n", "def main():\n", " test = TestCompress()\n", " compress_string = CompressString()\n", + " compress_string_2 = CompressString_2()\n", " test.test_compress(compress_string.compress)\n", + " test.test_compress(compress_string_2.compress_2)\n", "\n", "\n", "if __name__ == '__main__':\n", @@ -170,22 +211,30 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, + "execution_count": 24, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Success: test_compress\n" + "Success: compress\n", + "Success: compress_2\n" ] } ], "source": [ "%run -i test_compress.py" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] } ], "metadata": { @@ -204,9 +253,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.0" + "version": "3.6.1" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/arrays_strings/compress/test_compress.py b/arrays_strings/compress/test_compress.py index 6395f11..23beffa 100644 --- a/arrays_strings/compress/test_compress.py +++ b/arrays_strings/compress/test_compress.py @@ -10,13 +10,15 @@ class TestCompress(object): assert_equal(func('AAABCCDDDDE'), 'A3BC2D4E') assert_equal(func('BAAACCDDDD'), 'BA3C2D4') assert_equal(func('AAABAACCDDDD'), 'A3BA2C2D4') - print('Success: test_compress') + print('Success: %s' % func.__name__) def main(): test = TestCompress() compress_string = CompressString() + compress_string_2 = CompressString_2() test.test_compress(compress_string.compress) + test.test_compress(compress_string_2.compress_2) if __name__ == '__main__':