{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Dictionaries\n",
    "Video Outline:\n",
    "1. Introduction to Dictionaries\n",
    "2. Creating Dictionaries\n",
    "3. Accessing Dictionary Elements\n",
    "4. Modifying Dictionary Elements\n",
    "5. Dictionary Methods\n",
    "6. Iterating Over Dictionaries\n",
    "7. Nested Dictionaries\n",
    "8. Dictionary Comprehensions\n",
    "9. Practical Examples and Common Errors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Introduction to Dictionaries\n",
    "\n",
    "Dictionaries are unordered collections of items. They store data in key-value pairs.\n",
    "Keys must be unique and immutable (e.g., strings, numbers, or tuples), while values can be of any type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "## Creating Dictionaries\n",
    "empty_dict={}\n",
    "print(type(empty_dict))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "empty_dict=dict()\n",
    "empty_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish', 'age': 32, 'grade': 24}\n",
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "student={\"name\":\"Krish\",\"age\":32,\"grade\":24}\n",
    "print(student)\n",
    "print(type(student))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 24, 'age': 32}\n"
     ]
    }
   ],
   "source": [
    "# Single key is slways used\n",
    "student={\"name\":\"Krish\",\"age\":32,\"name\":24}\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish', 'age': 32, 'grade': 'A'}\n"
     ]
    }
   ],
   "source": [
    "## accessing Dictionary Elements\n",
    "student={\"name\":\"Krish\",\"age\":32,\"grade\":'A'}\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A\n",
      "32\n",
      "A\n",
      "None\n",
      "Not Available\n"
     ]
    }
   ],
   "source": [
    "## Accessing Dictionary elements\n",
    "print(student['grade'])\n",
    "print(student['age'])\n",
    "\n",
    "## Accessing using get() method\n",
    "print(student.get('grade'))\n",
    "print(student.get('last_name'))\n",
    "print(student.get('last_name',\"Not Available\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish', 'age': 32, 'grade': 'A'}\n"
     ]
    }
   ],
   "source": [
    "## Modifying Dicitonary Elements\n",
    "## Dictionary are mutable,so you can add, update or delete elements\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish', 'age': 33, 'grade': 'A'}\n",
      "{'name': 'Krish', 'age': 33, 'grade': 'A', 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "student[\"age\"]=33  ##update value for the key\n",
    "print(student)\n",
    "student[\"address\"]=\"India\" ## added a new key and value\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish', 'age': 33, 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "del student['grade'] ## delete key and value pair\n",
    "\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['name', 'age', 'address'])\n",
      "dict_values(['Krish', 33, 'India'])\n",
      "dict_items([('name', 'Krish'), ('age', 33), ('address', 'India')])\n"
     ]
    }
   ],
   "source": [
    "## Dictionary methods\n",
    "\n",
    "keys=student.keys() ##get all the keys\n",
    "print(keys)\n",
    "values=student.values() ##get all values\n",
    "print(values)\n",
    "\n",
    "items=student.items() ##get all key value pairs\n",
    "print(items)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish1', 'age': 33, 'address': 'India'}\n",
      "{'name': 'Krish1', 'age': 33, 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "## shallow copy\n",
    "student_copy=student\n",
    "print(student)\n",
    "print(student_copy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish2', 'age': 33, 'address': 'India'}\n",
      "{'name': 'Krish2', 'age': 33, 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "student[\"name\"]=\"Krish2\"\n",
    "print(student)\n",
    "print(student_copy)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish2', 'age': 33, 'address': 'India'}\n",
      "{'name': 'Krish2', 'age': 33, 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "student_copy1=student.copy() ## shallow copy\n",
    "print(student_copy1)\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Krish2', 'age': 33, 'address': 'India'}\n",
      "{'name': 'KRish3', 'age': 33, 'address': 'India'}\n"
     ]
    }
   ],
   "source": [
    "student[\"name\"]=\"KRish3\"\n",
    "print(student_copy1)\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name\n",
      "age\n",
      "address\n"
     ]
    }
   ],
   "source": [
    "### Iterating Over Dictionaries\n",
    "## You can use loops to iterate over dictionatries, keys,values,or items\n",
    "\n",
    "## Iterating over keys\n",
    "for keys in student.keys():\n",
    "    print(keys)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "KRish3\n",
      "33\n",
      "India\n"
     ]
    }
   ],
   "source": [
    "## Iterate over values\n",
    "for value in student.values():\n",
    "    print(value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name:KRish3\n",
      "age:33\n",
      "address:India\n"
     ]
    }
   ],
   "source": [
    "## Iterate over key value pairs\n",
    "for key,value in student.items():\n",
    "    print(f\"{key}:{value}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'student1': {'name': 'Krish', 'age': 32}, 'student2': {'name': 'Peter', 'age': 35}}\n"
     ]
    }
   ],
   "source": [
    "## Nested Disctionaries\n",
    "students={\n",
    "    \"student1\":{\"name\":\"Krish\",\"age\":32},\n",
    "    \"student2\":{\"name\":\"Peter\",\"age\":35}\n",
    "}\n",
    "print(students)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Peter\n",
      "35\n"
     ]
    }
   ],
   "source": [
    "## Access nested dictionaries elementss\n",
    "print(students[\"student2\"][\"name\"])\n",
    "print(students[\"student2\"][\"age\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_items([('student1', {'name': 'Krish', 'age': 32}), ('student2', {'name': 'Peter', 'age': 35})])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "students.items()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "student1:{'name': 'Krish', 'age': 32}\n",
      "name:Krish\n",
      "age:32\n",
      "student2:{'name': 'Peter', 'age': 35}\n",
      "name:Peter\n",
      "age:35\n"
     ]
    }
   ],
   "source": [
    "## Iterating over nested dictionaries\n",
    "for student_id,student_info in students.items():\n",
    "    print(f\"{student_id}:{student_info}\")\n",
    "    for key,value in student_info.items():\n",
    "        print(f\"{key}:{value}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}\n"
     ]
    }
   ],
   "source": [
    "## Dictionary Comphrehension\n",
    "squares={x:x**2 for x in range(5)}\n",
    "print(squares)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0: 0, 2: 4, 4: 16, 6: 36, 8: 64}\n"
     ]
    }
   ],
   "source": [
    "## Condition dictionary comprehension\n",
    "evens={x:x**2 for x in range(10) if x%2==0}\n",
    "print(evens)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1: 1, 2: 2, 3: 3, 4: 4}\n"
     ]
    }
   ],
   "source": [
    "## Practical Examples\n",
    "\n",
    "## USe a dictionary to count he frequency of elements in list\n",
    "\n",
    "numbers=[1,2,2,3,3,3,4,4,4,4]\n",
    "frequency={}\n",
    "\n",
    "for number in numbers:\n",
    "    if number in frequency:\n",
    "        frequency[number]+=1\n",
    "    else:\n",
    "        frequency[number]=1\n",
    "print(frequency)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 1, 'b': 3, 'c': 4}\n"
     ]
    }
   ],
   "source": [
    "## Merge 2 dictionaries into one\n",
    "\n",
    "dict1={\"a\":1,\"b\":2}\n",
    "dict2={\"b\":3,\"c\":4}\n",
    "merged_dict={**dict1,**dict2}\n",
    "print(merged_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Conclusion\n",
    "Dictionaries are powerful tools in Python for managing key-value pairs. They are used in a variety of real-world scenarios, such as counting word frequency, grouping data, storing configuration settings, managing phonebooks, tracking inventory, and caching results. Understanding how to leverage dictionaries effectively can greatly enhance the efficiency and readability of your code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
