{ "cells": [ { "cell_type": "markdown", "id": "a6651c01", "metadata": {}, "source": [ "--- \n", " \n", "\n", "

Department of Data Science

\n", "

Course: Tools and Techniques for Data Science

\n", "\n", "---\n", "

Instructor: Muhammad Arif Butt, Ph.D.

" ] }, { "cell_type": "markdown", "id": "a363bc39", "metadata": {}, "source": [ "

Lecture 2.6

" ] }, { "cell_type": "markdown", "id": "630ea759", "metadata": {}, "source": [ "\"Open" ] }, { "cell_type": "markdown", "id": "95de41a5", "metadata": {}, "source": [ "## _Python-Tuples.ipynb_\n", "#### [Click me to learn more about Python Tuples](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)" ] }, { "cell_type": "markdown", "id": "0f75a9de", "metadata": {}, "source": [ " " ] }, { "cell_type": "markdown", "id": "3813f231", "metadata": {}, "source": [ "> **A Tuple is a numerically ordered sequence of elements that can store elements of heterogeneous types, is iterable, immutable and allows duplicate elements.**" ] }, { "cell_type": "markdown", "id": "a2e370e3", "metadata": {}, "source": [ "- Like Lists, a Tuple in Python is also an ordered collection of values.\n", "- Like Lists, a Tuple is created by placing comma separated values, but in parenthesis rather square brackets. \n", "- Like List, a Tuple also allows us to store elements of different data types in one container.\n", "- Unlike List, it is not possible to add, remove, or modify values in a Tuple, so you can think of tuples as immutable Lists.\n", "- Apart from this, every operation that we can perform on Lists that do not modify them, can be performed on Tuples as well.\n", "- To be honest, Tuples are not used as often as Lists in programming, but are used when immutability is necessary.\n", "- When to prefer Tuples over Lists?\n", " - While passing an object to a function, if you want to make sure that the object does not get changed, then Tuple become your solution. So Tuples provides a convenient source of data integrity.\n", " - Similarly, since functions can return only one value, if you want a function to return more than one value, you pack your result in a tuple and return it\n", " - Manipulating elements of a Tuple is far more efficient than manipulating elements of a List.\n", " - Tuples being immutable are used in Dictionaries as keys (which are immutable)." ] }, { "cell_type": "markdown", "id": "7c109b0c", "metadata": {}, "source": [ "## Learning agenda of this notebook\n", "1. How to create Tuples?\n", "2. Proof of concepts: Tuples are heterogeneous, ordered, nested, immutable, and allow duplicate elements\n", "3. Different ways to access elements of a Tuple?\n", "4. Slicing a Tuple\n", "5. Tuple concatenation and repetition\n", "6. Being immutable, you cannot add elements to a Tuple\n", "7. Being immutable, you cannot remove elemenst from a Tuple\n", "8. Converting string object to Tuple and vice-versa (using type casting, `split()` and `join()`)\n", "9. Tuple methods\n", "10. Sorting a Tuple using built-in `sorted()` function" ] }, { "cell_type": "code", "execution_count": 16, "id": "a0ce27db", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on class tuple in module builtins:\n", "\n", "class tuple(object)\n", " | tuple(iterable=(), /)\n", " | \n", " | Built-in immutable sequence.\n", " | \n", " | If no argument is given, the constructor returns an empty tuple.\n", " | If iterable is specified the tuple is initialized from iterable's items.\n", " | \n", " | If the argument is a tuple, the return value is the same object.\n", " | \n", " | Built-in subclasses:\n", " | asyncgen_hooks\n", " | UnraisableHookArgs\n", " | \n", " | Methods defined here:\n", " | \n", " | __add__(self, value, /)\n", " | Return self+value.\n", " | \n", " | __contains__(self, key, /)\n", " | Return key in self.\n", " | \n", " | __eq__(self, value, /)\n", " | Return self==value.\n", " | \n", " | __ge__(self, value, /)\n", " | Return self>=value.\n", " | \n", " | __getattribute__(self, name, /)\n", " | Return getattr(self, name).\n", " | \n", " | __getitem__(self, key, /)\n", " | Return self[key].\n", " | \n", " | __getnewargs__(self, /)\n", " | \n", " | __gt__(self, value, /)\n", " | Return self>value.\n", " | \n", " | __hash__(self, /)\n", " | Return hash(self).\n", " | \n", " | __iter__(self, /)\n", " | Implement iter(self).\n", " | \n", " | __le__(self, value, /)\n", " | Return self<=value.\n", " | \n", " | __len__(self, /)\n", " | Return len(self).\n", " | \n", " | __lt__(self, value, /)\n", " | Return self\n" ] } ], "source": [ "t1 = (1, 2, 3, 4, 5) #tuple of integers\n", "t1 = 1, 2, 3, 4, 5\n", "print(\"t1: \", t1)\n", "\n", "t2 = (2.3, 5.6, 1.8) #tuple of floats\n", "print(\"t2: \", t2)\n", "\n", "t3 = ('hello', 'this', 'F', 'good show') #tuple of strings\n", "print(\"t3: \", t3)\n", "\n", "t4 = (True, False, True) # tuple of boolean values\n", "print(\"t4: \", t4)\n", "\n", "\n", "print(\"Type of t4 is: \", type(t4))" ] }, { "cell_type": "code", "execution_count": null, "id": "64ed8ede", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 18, "id": "a51ee7b3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t5: ()\n" ] } ], "source": [ "# creating empty tuple\n", "t5 = ()\n", "print(\"t5: \", t5)" ] }, { "cell_type": "code", "execution_count": 19, "id": "0d9fbff4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "t6: (25,)\n", "\n" ] } ], "source": [ "# to create a tuple with only one element is a bit tricky\n", "t6 = (25,) # note the comma, without it, Python will take it as int/float/string and not tuple\n", "print(\"\\nt6: \", t6)\n", "print(type(t6))" ] }, { "cell_type": "code", "execution_count": 21, "id": "3c2bd2e4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Arif', 30, 5.5, (10, 'rauf'))\n" ] } ], "source": [ "# Nested Tuple: a tuple can also have another tuple as an item\n", "t1 = (\"Arif\", 30, 5.5, (10,'rauf'))\n", "print(t1)" ] }, { "cell_type": "code", "execution_count": null, "id": "5200e1b2", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 20, "id": "810d75d3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t1: (1, 'Hello', [8, 'OK', 6], (1, 2, 'BYE'), 5.5)\n", "Type of t1 is: \n" ] } ], "source": [ "# Nested tuple: A tuple can also have another tuple, or list as an item\n", "t1 = (1, \"Hello\", [8, 'OK', 6], (1, 2, 'BYE'), 5.5)\n", "print(\"t1: \", t1)\n", "print(\"Type of t1 is: \", type(t1))" ] }, { "cell_type": "markdown", "id": "48f77dc4", "metadata": {}, "source": [ "## 2. Proof of Concepts:" ] }, { "cell_type": "markdown", "id": "00a2ff5d", "metadata": {}, "source": [ "### a. Tuples are Heterogeneous\n", "- Like Lists, Tuples are heterogeneous, as their elements/items can be of any data type" ] }, { "cell_type": "code", "execution_count": 21, "id": "7c3a9b9c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t1: ('Arif', 30, 5.5)\n" ] } ], "source": [ "t1 = (\"Arif\", 30, 5.5)\n", "print(\"t1: \", t1)" ] }, { "cell_type": "markdown", "id": "f7ef359e", "metadata": {}, "source": [ "### b. Tuples are ordered\n", "- Like Lists Tuples are ordered.\n", "- Tuples are ordered means every element is associated by an index.\n", "- Every time you access tuple elements they will show up in same sequence. \n", "- Moreover, two tuples having same elements in different order are not same." ] }, { "cell_type": "code", "execution_count": 22, "id": "8c570d52", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(140597048184448, 140597047356352, False, False)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = (1, 2, 3)\n", "b = (2, 3, 1)\n", "id(a), id(b), a is b, a == b" ] }, { "cell_type": "markdown", "id": "251c05b7", "metadata": {}, "source": [ "### c. Tuples are immutable\n", "- Unlike Lists Tuples are immutable\n", "- Means once a tuple object is created, you CANNOT make changes to it and modify its elements" ] }, { "cell_type": "code", "execution_count": 23, "id": "8d0f40de", "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_27657/769081338.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Tuples are immutable, i.e., tuple elements cannot be changed\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mnumbers\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m30\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mnumbers\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m15\u001b[0m \u001b[0;31m# this will generate an error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "# Tuples are immutable, i.e., tuple elements cannot be changed\n", "numbers = (10, 20, 30)\n", "numbers[2] = 15 # this will generate an error" ] }, { "cell_type": "code", "execution_count": null, "id": "80c29ede", "metadata": {}, "outputs": [], "source": [ "# Tupple however can be reassigned\n", "numbers = (10, 20, 30)\n", "numbers = (1, 2, 3) # A tupple can be reassigned\n", "numbers" ] }, { "cell_type": "markdown", "id": "1e8e4bc4", "metadata": {}, "source": [ "Remember the tuple object `(10,20,20)` in memory has become an orphan, since the numbers variable is now pointing to another tuple object `(1,2,3)` in memory. The unreferenced tuple object will be garbage collected by Python garbage collector" ] }, { "cell_type": "code", "execution_count": 24, "id": "4fc9e430", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 'Hello', [8, 'Not OK', 6], (1, 2, 'BYE'), 5.5)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A List within a tuple is still mutable\n", "t1 = (1, \"Hello\", [8, 'OK', 6], (1, 2, 'BYE'), 5.5)\n", "t1[2][1] = 'Not OK' # will work fine\n", "t1" ] }, { "cell_type": "markdown", "id": "8a459d21", "metadata": {}, "source": [ "### d. Tuples can have duplicate elements" ] }, { "cell_type": "code", "execution_count": 25, "id": "0a910e6f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Arif', 'Rauf', 'Hadeed', 'Arif', 'Mujahid')\n" ] } ], "source": [ "# Like Lists, Tuples allow duplicate elements\n", "names = ('Arif', 'Rauf', 'Hadeed', 'Arif', 'Mujahid')\n", "print(names)" ] }, { "cell_type": "markdown", "id": "32a0f7b9", "metadata": {}, "source": [ "### e. Tuples can be nested to arbitrary depth\n", "- Like Lists, you can have tuples within tuples and that can be done to an arbitrary depth. You are only restricted to the available memory on your system" ] }, { "cell_type": "code", "execution_count": 26, "id": "e087c00b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "((1, 2, 3, (4, 5), (6, 7, 8, 9), 10, 11),\n", " (1, 2, 3, (4, 5, (6, 7, 8, (9, 10, 11)))))" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A tuple having two sub-tuples within it\n", "a = (1,2,3,(4,5),(6,7,8,9),10,11)\n", "# A tuple having a sub-tuple, which is further having a sub-tuple and that again having a subtuple\n", "b = (1,2,3,(4,5,(6,7,8,(9,10,11))))\n", "a, b" ] }, { "cell_type": "markdown", "id": "1f8ac237", "metadata": {}, "source": [ "### f. Packing and Unpacking Tuples" ] }, { "cell_type": "code", "execution_count": 27, "id": "6b94e91a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "learning fun Arif\n", "\n" ] } ], "source": [ "# you can unpack tuple elements\n", "t1 = ('learning', 'is', 'fun', 'with', 'Arif')\n", "a, b, c, d, e = t1 # the number of variables on the left must match the length of tuple\n", "print (a, c, e)\n", "print(type(a))" ] }, { "cell_type": "code", "execution_count": 28, "id": "b63654ee", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('learning', 'is', 'fun', 'with', 'Arif')\n", "\n" ] } ], "source": [ "# you can pack individual elements to a tuple\n", "t1 = a,b,c,d,e\n", "print(t1)\n", "print(type(t1))" ] }, { "cell_type": "markdown", "id": "418db83b", "metadata": {}, "source": [ "## 3. Different ways to access Elements of a Tuple\n", "- Since Tuple like List is of type Sequence, and any component within a sequence can be accessed by entrying an index within square brackets. So naturally this must work for Tuple as well\n", "- Similarly, if we want to find out the index of a specific item/character, we can use the `index()` method of Tuple class" ] }, { "cell_type": "code", "execution_count": 29, "id": "bbc96405", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.5\n", "(10, 'rauf')\n", "i\n", "rauf\n" ] } ], "source": [ "#You can access elements of tuple using indexing which starts from zero\n", "t1 = (\"Arif\", 30, 5.5, (10,'rauf'))\n", "\n", "print(t1[2]) #accessing element of tuple at index2\n", "print(t1[3]) #accessing element of tuple at index3, which is again a tuple\n", "\n", "#accessing Nested tuple element\n", "print(t1[0][2]) #accessing third character of a tuple element at index 0\n", "print(t1[3][1]) #accessing second element of Nested tuple at index 3" ] }, { "cell_type": "code", "execution_count": 30, "id": "c0d21f34", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(10, 'rauf')\n", "5.5\n" ] } ], "source": [ "#Negative indexing starts looking at the tuple from the right hand side\n", "t1 = (\"Arif\", 30, 5.5, (10,'rauf'))\n", "print(t1[-1]) #accessing last element\n", "print(t1[-2]) #accessing second last element" ] }, { "cell_type": "code", "execution_count": null, "id": "eb601e4a", "metadata": {}, "outputs": [], "source": [ "help(t1.index)" ] }, { "cell_type": "code", "execution_count": 31, "id": "d42c7653", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "mytuple: (27, 4.5, 'arif', 64, 'hadeed', 19, 'arif')\n", "mytuple.index(3): 2\n" ] } ], "source": [ "# index(value) method is used when you know the tuple element and wants to get its index\n", "# index(value) method returns the index of the first matched item with its only argument\n", "mytuple = (27, 4.5, 'arif', 64, 'hadeed', 19, 'arif')\n", "print(\"\\nmytuple: \", mytuple)\n", "print(\"mytuple.index(3): \", mytuple.index('arif'))" ] }, { "cell_type": "markdown", "id": "c9517d91", "metadata": {}, "source": [ "## 4. Slicing Tuples\n", "- Like anyother sequence object we can perform slicing with tuples as well.\n", "- Slicing is the process of obtaining a portion of a tuple by using its indices.\n", "- Given a tuple, we can use the following template to slice it and obtain a sublist:\n", "```\n", "mytuple[start:end:step]\n", "```\n", "\n", "- **start** is the index from where we want the subtuple to start.If start is not provided, slicing starts from the beginning.\n", "- **end** is the index where we want our subtuple to end (not inclusive in the subtuple). If end is not provided, slicing goes till the last element of the tuple.\n", "- **step** is the step through which we want to skip elements in the tuple. The default step is 1, so we iterate through every element of the tuple." ] }, { "cell_type": "code", "execution_count": 32, "id": "d533f237", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i')" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1 = ('a','b','c','d','e','f','g','h','i')\n", "t1" ] }, { "cell_type": "code", "execution_count": 33, "id": "fc7f5721", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i')" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1[::]" ] }, { "cell_type": "code", "execution_count": 34, "id": "bacb22ad", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('d', 'e', 'f', 'g', 'h', 'i')" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1[3:]" ] }, { "cell_type": "code", "execution_count": 35, "id": "fda45faa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'b', 'c', 'd')" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1[:4]" ] }, { "cell_type": "code", "execution_count": null, "id": "abafa446", "metadata": {}, "outputs": [], "source": [ "t1[2:5]" ] }, { "cell_type": "code", "execution_count": null, "id": "17127f79", "metadata": {}, "outputs": [], "source": [ "t1[:-2]" ] }, { "cell_type": "code", "execution_count": null, "id": "0a4ca863", "metadata": {}, "outputs": [], "source": [ "t1[-1]" ] }, { "cell_type": "code", "execution_count": null, "id": "c4cf41ba", "metadata": {}, "outputs": [], "source": [ "# Slicing by using strides\n", "print(t1[::]) # A default step of 1\n", "print(t1[::1]) # A step of 1\n", "print(t1[::2]) # A step of 2\n", "print(t1[::3]) # A step of 3" ] }, { "cell_type": "code", "execution_count": null, "id": "44359432", "metadata": {}, "outputs": [], "source": [ "# Reverse slicing\n", "print(t1[::-1]) # Take 1 step back each time\n", "print(t1[5:1:-1]) # Take 1 step back each time\n", "#if start is less than end in case of a negative step, it will return empty string\n", "print(t1[2:10:-1])\n", "print(t1[::-2]) # Take 2 steps back" ] }, { "cell_type": "code", "execution_count": null, "id": "8221022c", "metadata": {}, "outputs": [], "source": [ "# You CANNOT use slice operator on the left side of assignment as tuple is immutable\n", "t1 = (1, 2, 3, 4, 5, 6, 7)\n", "#t1[2:4] = ['a', 'b', 'c'] # will generate an error as 'tuple' object does not support item assignment" ] }, { "cell_type": "markdown", "id": "8f109f45", "metadata": {}, "source": [ "## 5. Tuple Concatenation and Repetition\n", "- The `+` operator is used to concatenate two or more tuples\n", "- The `*` operator is used to repeat or replicate" ] }, { "cell_type": "markdown", "id": "4063124d", "metadata": {}, "source": [ "### a. Concatenating Tuples" ] }, { "cell_type": "code", "execution_count": 36, "id": "5db695de", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "((1, 2, 3), (1, 2, 3, 4, 5), (0, 1, 2, 3, 4, 5))" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Add some elements to the end of an existing tuple using concatenation operator\n", "a = (1,2,3)\n", "b = a + (4,5)\n", "# Add some elements to the beginning of an existing tuple using concatenation operator\n", "c = (0,) + b\n", "a, b, c" ] }, { "cell_type": "code", "execution_count": 37, "id": "65c304f4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('fruits', 'bread', 'veggies', 'meat', 'spices', 'burger')\n" ] } ], "source": [ "# use + operator to concatenate two tuples\n", "food_items1 = ('fruits', 'bread', 'veggies')\n", "food_items2 = ('meat', 'spices', 'burger')\n", "food = food_items1 + food_items2\n", "print(food)" ] }, { "cell_type": "code", "execution_count": 38, "id": "895eb9a4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5, 3.4, 'hello', 31, 9.7, 'bye')\n" ] } ], "source": [ "# You can concatenate two heterogeneous tuples\n", "t1 = (5, 3.4, 'hello')\n", "t2 = (31, 9.7, 'bye')\n", "t3 = t1 + t2\n", "print(t3)" ] }, { "cell_type": "code", "execution_count": 39, "id": "0845f519", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 2, 3, 4, 5, 6, (7, 8))\n" ] } ], "source": [ "num1 = (1,2,3)\n", "num2 = num1 + (4, 5, 6, (7, 8))\n", "print (num2)" ] }, { "cell_type": "markdown", "id": "617419b0", "metadata": {}, "source": [ "### b. Replicating Tuples" ] }, { "cell_type": "code", "execution_count": 40, "id": "d4208107", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Arif', 'Hadeed', 'Mujahid', 'Arif', 'Hadeed', 'Mujahid', 'Arif', 'Hadeed', 'Mujahid')\n" ] } ], "source": [ "# use tuple * n syntax to create large tuples by repeating the tuple n times\n", "name = ('Arif', 'Hadeed', 'Mujahid')\n", "a = name * 3\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 41, "id": "a9a6308a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')\n" ] }, { "data": { "text/plain": [ "tuple" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#tuple of 100 A's\n", "buf = ('A',)\n", "newbuf = buf * 100\n", "print(newbuf)\n", "type(newbuf)" ] }, { "cell_type": "markdown", "id": "0557d8ff", "metadata": {}, "source": [ "## 6. Being immutable, you cannot add elements to a tuple (in list this is possible using `append`, `extend`, and `insert`)" ] }, { "cell_type": "code", "execution_count": 42, "id": "4ca664fe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", " myfamily tuple: ('Farooq', 'Rauf', 'Hadeed')\n" ] }, { "ename": "AttributeError", "evalue": "'tuple' object has no attribute 'insert'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_27657/1169247384.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmyfamily\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"Farooq\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Rauf'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Hadeed'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"\\n myfamily tuple: \"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmyfamily\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mmyfamily\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Arif'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# will generate an error as tuple object has no attribute 'insert'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mAttributeError\u001b[0m: 'tuple' object has no attribute 'insert'" ] } ], "source": [ "myfamily = (\"Farooq\", 'Rauf', 'Hadeed')\n", "print(\"\\n myfamily tuple: \", myfamily)\n", "myfamily.insert(2,'Arif') # will generate an error as tuple object has no attribute 'insert'\n" ] }, { "cell_type": "markdown", "id": "ae40dd9e", "metadata": {}, "source": [ "## 7. Being immutable, you cannot remove elements from a tuple (in list this is possible using `pop` and `remove` methods)" ] }, { "cell_type": "code", "execution_count": 45, "id": "33f7704a", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'tuple1' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/1t/g3ylw8h50cjdqmk5d6jh1qmm0000gn/T/ipykernel_27657/527872821.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;31m# However, you can delete an entire tuple object using del keyword\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mtuple1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtuple1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: name 'tuple1' is not defined" ] } ], "source": [ "tuple1 = ('learning', 'is', 'fun', 'with', 'arif', 'butt')\n", "\n", "#You cannot delete items from a tuple using del keyword\n", "#del tuple1[3] # will generate an error as tuple object doesn't support item deletion\n", "\n", "# However, you can assign a new tuple object to the reference tuple1\n", "tuple1 = (1, 2, 3, 'arif')\n", "# However, you can delete an entire tuple object using del keyword\n", "#del tuple1\n", "#print(tuple1)\n", "\n" ] }, { "cell_type": "markdown", "id": "0f4dd1c2", "metadata": {}, "source": [ "## 8. Converting String object to List/Tuple and vice-versa" ] }, { "cell_type": "markdown", "id": "f9dcb124", "metadata": {}, "source": [ "### a. Type Casting" ] }, { "cell_type": "code", "execution_count": 46, "id": "71af910c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original string: Learning is fun and its type is: \n", "t1: ('L', 'e', 'a', 'r', 'n', 'i', 'n', 'g', ' ', 'i', 's', ' ', 'f', 'u', 'n') and its type is: \n" ] } ], "source": [ "# convert a string into tuple using tuple()\n", "str1 = 'Learning is fun' #this is a string\n", "\n", "print(\"Original string: \", str1, \"and its type is: \", type(str1))\n", "t1 = tuple(str1)\n", "print(\"t1: \", t1, \"and its type is: \", type(t1))" ] }, { "cell_type": "code", "execution_count": null, "id": "bcf7ce2f", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "5e9e7346", "metadata": {}, "source": [ "### b. Use `str.split()` to Split a Tuple into Strings\n", "- Used to tokenize a string based on some delimiter, which can be stored in a tuple\n", "- It returns a list, so we need to type cast the returned object to a tuple" ] }, { "cell_type": "code", "execution_count": 6, "id": "993e0fef", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on built-in function split:\n", "\n", "split(sep=None, maxsplit=-1) method of builtins.str instance\n", " Return a list of the words in the string, using sep as the delimiter string.\n", " \n", " sep\n", " The delimiter according which to split the string.\n", " None (the default value) means split according to any whitespace,\n", " and discard empty strings from the result.\n", " maxsplit\n", " Maximum number of splits to do.\n", " -1 (the default value) means no limit.\n", "\n" ] } ], "source": [ "str1 = \"\"\n", "help(str1.split)" ] }, { "cell_type": "code", "execution_count": 47, "id": "c5d68224", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Learning', 'is', 'fun')\n", "\n" ] } ], "source": [ "str1 = 'Learning is fun' #this is a string\n", "t1 = tuple(str1.split(' ')) # The split() method returns a list, which you can typecast to a tuple\n", "print(t1)\n", "print(type(t1))" ] }, { "cell_type": "code", "execution_count": 48, "id": "0ae62a11", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Data S', 'ien', 'e is GR8 Degree')\n", "\n" ] } ], "source": [ "str2 = \"Data Science is GR8 Degree\" #this is a string\n", "t2 = tuple(str2.split('c'))\n", "print(t2)\n", "print(type(t2))" ] }, { "cell_type": "markdown", "id": "1096daf9", "metadata": {}, "source": [ "### c. Use `str.join()` to Join Strings into a Tuple\n", "- The `str.join()` is the reverse of split() method, and is used to joing multiple strings by inserting the string in between on which this method is called\n", "- Remember, you can pass any iterable as argument to `str.join()` method" ] }, { "cell_type": "code", "execution_count": 13, "id": "0c20a59f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on built-in function join:\n", "\n", "join(iterable, /) method of builtins.str instance\n", " Concatenate any number of strings.\n", " \n", " The string whose method is called is inserted in between each given string.\n", " The result is returned as a new string.\n", " \n", " Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'\n", "\n" ] } ], "source": [ "str = \"\"\n", "help(str.join)" ] }, { "cell_type": "code", "execution_count": 49, "id": "f04b4019", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('This', 'is', 'getting', 'more', 'and', 'more', 'interesting')" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1 = ('This', 'is', 'getting', 'more', 'and', 'more', 'interesting')\n", "t1" ] }, { "cell_type": "code", "execution_count": 50, "id": "04ecbbc7", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('This is getting more and more interesting', str)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str2 = ' '.join(t1)\n", "str2, type(str2)" ] }, { "cell_type": "code", "execution_count": 51, "id": "2bb77698", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This # is # getting # more # and # more # interesting\n", "\n" ] } ], "source": [ "delimiter = \" # \"\n", "str3 = delimiter.join(t1)\n", "print(str3)\n", "print(type(str3))" ] }, { "cell_type": "code", "execution_count": null, "id": "a06d0265", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "fbf88b2e", "metadata": {}, "source": [ "## 9. Misc Tuple Methods in Python\n", "- Tuples have built-in methods, but not as many as Lists do. Lets look at two of them:\n", " - The `t1.index(val)` method takes the value and returns the first index where that value resides in the tuple\n", " - The `t1.count(val)` method takes exactly one argument and returns the number of times a that value occurs in a tuple" ] }, { "cell_type": "code", "execution_count": 52, "id": "9a32d56d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "t1 = (3, 8, 1, 6, 0, 8, 4)\n", "rv = t1.index(6)\n", "print(rv)" ] }, { "cell_type": "code", "execution_count": 54, "id": "8dfa6b70", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "t1 = (3, 8, 1, 6, 8, 0, 8, 4)\n", "rv = t1.count(8)\n", "print(rv)" ] }, { "cell_type": "markdown", "id": "4f48dd83", "metadata": {}, "source": [ "**Like Lists, you can apply `max()`, `min()`, and `sum()` functions on tuples with numeric elements**" ] }, { "cell_type": "code", "execution_count": 15, "id": "2f025aa2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "length of list: 7\n", "max element in list: 8\n", "min element in list: 0\n", "Sum of element in list: 30\n" ] } ], "source": [ "t1 = (3, 8, 1, 6, 0, 8, 4)\n", "print(\"length of list: \", len(t1))\n", "print(\"max element in list: \", max(t1))\n", "print(\"min element in list: \",min(t1))\n", "print(\"Sum of element in list: \",sum(t1))" ] }, { "cell_type": "markdown", "id": "bf47a9e8", "metadata": {}, "source": [ "**Like Lists, you can apply `in` and `not in` membership operators on Tuples**" ] }, { "cell_type": "code", "execution_count": 55, "id": "689db389", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n", "True\n" ] } ], "source": [ "t1 = (3, 8, 1, 6, 0, 8, 4)\n", "rv1 = 9 in t1\n", "print(rv1)\n", "\n", "rv2 = 9 not in t1\n", "print(rv2)\n", "\n", "\n", "t2 = (\"XYZ\", \"ABC\", \"MNO\", \"ARIF\")\n", "rv3 = \"ARIF\" in t2\n", "print(rv3)\n", "\n" ] }, { "cell_type": "markdown", "id": "aaaa0c01", "metadata": {}, "source": [ "**Comparing Objects and Values**" ] }, { "cell_type": "code", "execution_count": 56, "id": "e6a50444", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "140597046554096 140597046554096\n", "True\n", "True\n" ] } ], "source": [ "#In case of strings, both variables str1 and str2 refers to the same memory location containing string object 'hello'\n", "str1 = 'hello'\n", "str2 = 'hello'\n", "print(id(str1), id(str2))\n", "\n", "print (str1 is str2) # is operator is checking the memory address (ID) of two strings\n", "print (str1 == str2) # == operator is checking the contents of two strings" ] }, { "cell_type": "code", "execution_count": null, "id": "a1c96bd0", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 15, "id": "8639f31f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "140597048251712 140597048247424\n", "False\n", "True\n" ] } ], "source": [ "#In case of tuples, both t1 and t2 refers to two different objects in the memory having same values\n", "t1 = (1, 2, 3)\n", "t2 = (1, 2, 3)\n", "print(id(t1), id(t2))\n", "\n", "print (t1 is t2) # is operator is checking the memory address (ID) of two tuples\n", "print (t1 == t2) # == operator is checking the contents of two tuples element by element" ] }, { "cell_type": "code", "execution_count": null, "id": "5f37b0ce", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "4d074020", "metadata": {}, "source": [ "## 10. Sorting a Tuple\n", "- Python’s built-in `sorted()` function can be used to sort iterable objects, such as lists, tuples, and dictionaries. - We have seen its usage in our Tuple session.\n", "- The `sorted()` function sorts the items of the specified iterable object and creates a new object with the newly sorted values.\n", "- It's syntax is as shown below:\n", "```\n", " sorted(object, key=None, reverse=False)\n", "```\n", "- Where:\n", " - `object`: the iterable object that you want to sort (required)\n", " - `key`: the function that allows you to perform custom sort operations (optional)\n", " - `reverse`: specifies whether the object should be sorted in descending order (optional)- default value is False" ] }, { "cell_type": "code", "execution_count": 57, "id": "4625d4b2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original Tuple = (3, 8, 1, 6, 0, 8, 4)\n", "Ascending Sort: [0, 1, 3, 4, 6, 8, 8]\n", "Descending Sort: [8, 8, 6, 4, 3, 1, 0]\n" ] } ], "source": [ "# Sorting a Dictionary by it values with numeric values\n", "\n", "t1 = (3, 8, 1, 6, 0, 8, 4)\n", "\n", "print(\"Original Tuple = \", t1)\n", "\n", "\n", "list1 = sorted(t1)\n", "list2 = sorted(t1, reverse=True)\n", "\n", "print(\"Ascending Sort: \", list1)\n", "print(\"Descending Sort: \", list2)" ] }, { "cell_type": "code", "execution_count": null, "id": "d8c14be7", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 58, "id": "4203d43f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original Tuple: ('XYZ', 'ABC', 'MNO', 'ARIF')\n", "Ascending Sort: ['ABC', 'ARIF', 'MNO', 'XYZ']\n", "Descending Sort: ['XYZ', 'MNO', 'ARIF', 'ABC']\n" ] } ], "source": [ "# Sorting a tuple with string values\n", "\n", "t1 = (\"XYZ\", \"ABC\", \"MNO\", \"ARIF\")\n", "print(\"Original Tuple: \", t1)\n", "\n", "list1 = sorted(t1)\n", "list2 = sorted(t1, reverse=True)\n", "\n", "print(\"Ascending Sort: \", list1)\n", "print(\"Descending Sort: \", list2)" ] }, { "cell_type": "markdown", "id": "cdcb5387", "metadata": {}, "source": [ "### b. Custom Sorting using `sorted()` Method" ] }, { "cell_type": "code", "execution_count": null, "id": "2c90cf5e", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "e03ac410", "metadata": {}, "source": [ "**Example 1: Suppose given a tuple with elements `('ccc', 'aaaa', 'd', 'bb')` and we want to sort it by length of strings inside the tuple so that the output is like : `('d', 'bb', 'ccc', 'aaaa)`**\n", "\n", "```\n", " sorted(iterable, key=None, reverse=False)\n", "```\n", "- We write a one argument function, and pass that function to the `key` parameter of `sorted()` function\n", "- The `sorted()` function will run this one argument function on all the elements of the tuple and return a single value, and build up a shadow list of those new values. \n", "- Suppose the one argument function in this case is the Python built-in function `len()`, which when called on every element of `tuple` will return a shadow list containing length of every string within the original tuple containing `[3,4,1,2]`\n", "- The `sorted()` function will then sort elements of the tuple based on the values of the shadow list and returns the required sorted list :)" ] }, { "cell_type": "code", "execution_count": 63, "id": "d4015aa1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['aaaa', 'bb', 'ccc', 'd']" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t1 = ('ccc', 'aaaa', 'd', 'bb')\n", "sorted(t1)" ] }, { "cell_type": "code", "execution_count": 64, "id": "ff103dab", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['d', 'bb', 'ccc', 'aaaa']" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#Example 1:\n", "t1 = ('ccc', 'aaaa', 'd', 'bb')\n", "sorted(t1, key=len)" ] }, { "cell_type": "markdown", "id": "e0a78fe8", "metadata": {}, "source": [ "**Example 2: Suppose given a tuple with elements `('abcz', 'xyza', 'bas', 'arif')` and we want to sort it by last character of strings within the tuple so that the output is like : `('xyza', 'arif', 'bas', 'abcz')`**\n", "\n", "```\n", " sorted(iterable, key=None, reverse=False)\n", "```\n", "- We write a one argument function, and pass that function to the `key` parameter of `sorted()` function\n", "- The `sorted()` function will run this one argument function on all the elements of the tuple and return a single value, and build up a shadow list of those new values. \n", "- This time the one argument function is a user defined function that receives a string and returns its last character. When called on every element of `tuple` will return a shadow list containing only the last character of every string within the original tuple containing `['z', 'a', 's', 'f']`\n", "- The `sorted()` function will then sort elements of the tuple based on the values of the shadow list and returns the required sorted list :)" ] }, { "cell_type": "code", "execution_count": 62, "id": "2587b323", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['xyza', 'arif', 'bas', 'abcz']\n", "('abcz', 'xyza', 'bas', 'arif')\n" ] } ], "source": [ "def last(s):\n", " return s[-1]\n", "\n", "t1 = ('abcz', 'xyza', 'bas', 'arif')\n", "rv = sorted(t1, key=last)\n", "print(rv)\n", "print(t1)" ] }, { "cell_type": "code", "execution_count": null, "id": "b77e3768", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "1bd4be02", "metadata": {}, "source": [ "## Check your Concepts\n", "\n", "Try answering the following questions to test your understanding of the topics covered in this notebook:\n", "\n", "1. How tuples are different from list?\n", "2. Can you add or remove elements in a tuple?\n", "3. How do you create a tuple with just one element?\n", "4. How do you convert a tuple to a list and vice versa?\n", "5. How to create a nested tuple?\n", "6. How to find a min, max value from a tuple?\n", "7. How to compare two tuples, without iteration? (Hint: cmp)\n", "8. How to find the index of a specific element of a tuple?\n", "9. How to fiund the count of occurrence of element in Python Tuple?\n", "10.How to delete Tuple in Python ?\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b0cf3eb0", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" } }, "nbformat": 4, "nbformat_minor": 5 }