Session 4

๐Ÿ“‹ Lists & Tuples

Python's most versatile data structures

๐Ÿ“š 12 Topics โฑ๏ธ 50 min read ๐ŸŽฏ Essential Level

๐Ÿ—บ๏ธ What You'll Learn

๐Ÿ“ Creating Lists
๐Ÿ” Indexing & Slicing
โž• Adding & Removing Items
๐Ÿ”„ List Methods
๐Ÿ”’ Tuples (Immutable Lists)
๐Ÿ“ฆ Nested Structures

๐Ÿ“˜ Same topic in the course notebook

Session_4 Data Structures Part I covers lists, indexing, slicing, and methodsโ€”same as this lesson. Try the notebook next.

๐Ÿš‚

Think of Lists Like a Train!

    ๐Ÿš‚โ•โ•โ•โ•ฆโ•โ•โ•โ•ฆโ•โ•โ•โ•ฆโ•โ•โ•โ•ฆโ•โ•โ•โ•ฆโ•โ•โ•โ•—
         โ•‘ ๐ŸŽ โ•‘ ๐ŸŠ โ•‘ ๐Ÿ‹ โ•‘ ๐Ÿ‡ โ•‘ ๐Ÿ‰ โ•‘
         โ•‘ [0]โ•‘ [1]โ•‘ [2]โ•‘ [3]โ•‘ [4]โ•‘
    โ•โ•โ•โ•โ•โ•ฉโ•โ•โ•โ•ฉโ•โ•โ•โ•ฉโ•โ•โ•โ•ฉโ•โ•โ•โ•ฉโ•โ•โ•โ•
    
    โ€ข Each car holds one item
    โ€ข Cars are numbered (indexed)
    โ€ข You can add/remove cars
    โ€ข You can look inside any car
          

A List is an ordered collection where each item has a position number!

๐Ÿ“ Creating Lists

4.1

๐ŸŽฏ What is a List?

A list is an ordered, mutable (changeable) collection of items. It can hold different types of data and duplicate values.

Python From Source
# Creating lists from Session 4

# Empty list
empty_list = []
print("Empty list:", empty_list)

# List with numbers
numbers = [1, 2, 3, 4, 5]
print("Numbers:", numbers)

# List with strings
fruits = ["apple", "banana", "cherry"]
print("Fruits:", fruits)

# Mixed types - Python allows this!
mixed = [1, "hello", 3.14, True, None]
print("Mixed:", mixed)

# List with duplicates
duplicates = [1, 2, 2, 3, 3, 3]
print("With duplicates:", duplicates)

# Using list() constructor
from_string = list("hello")
print("From string:", from_string)
Output
Empty list: []
Numbers: [1, 2, 3, 4, 5]
Fruits: ['apple', 'banana', 'cherry']
Mixed: [1, 'hello', 3.14, True, None]
With duplicates: [1, 2, 2, 3, 3, 3]
From string: ['h', 'e', 'l', 'l', 'o']

๐Ÿ” Accessing List Elements

4.2

๐Ÿ“ Indexing

Each item in a list has a position number called an index. Python uses zero-based indexing - the first item is at index 0!

๐Ÿ”ข Understanding Indices

    List:      ["apple", "banana", "cherry", "date", "elderberry"]
    
    Positive:      0        1         2        3          4
                   โ†“        โ†“         โ†“        โ†“          โ†“
                 โ”Œโ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”
                 โ”‚ ๐ŸŽ โ”‚  โ”‚ ๐ŸŒ โ”‚   โ”‚ ๐Ÿ’ โ”‚   โ”‚ ๐Ÿ“… โ”‚    โ”‚ ๐Ÿซ โ”‚
                 โ””โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”˜
                   โ†‘        โ†‘         โ†‘        โ†‘          โ†‘
    Negative:     -5       -4        -3       -2         -1
    
    ๐Ÿ’ก Negative indices count from the end!
          
Python From Source
# Indexing from Session 4
fruits = ["apple", "banana", "cherry", "date", "elderberry"]

# Positive indexing (from start)
print("First item (index 0):", fruits[0])
print("Second item (index 1):", fruits[1])
print("Third item (index 2):", fruits[2])

# Negative indexing (from end)
print("Last item (index -1):", fruits[-1])
print("Second to last (index -2):", fruits[-2])

# Get length of list
print("List length:", len(fruits))
Output
First item (index 0): apple
Second item (index 1): banana
Third item (index 2): cherry
Last item (index -1): elderberry
Second to last (index -2): date
List length: 5
4.3

โœ‚๏ธ Slicing - Getting Multiple Items

Slicing lets you get a portion of a list using the syntax list[start:stop:step]

๐ŸŽฏ Slicing Rules

    list[start:stop:step]
    
    โ€ข start: Where to begin (included)
    โ€ข stop:  Where to end (NOT included!)
    โ€ข step:  How many to skip (default: 1)
    
    ๐ŸŽช Remember: Start is IN, Stop is OUT!
          
Python From Source
# Slicing from Session 4
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Basic slicing
print("First 3 items:", numbers[0:3])     # [0, 1, 2]
print("Items 3-6:", numbers[3:7])         # [3, 4, 5, 6]

# Shorthand notation
print("First 5:", numbers[:5])           # [0, 1, 2, 3, 4]
print("From index 5:", numbers[5:])     # [5, 6, 7, 8, 9]
print("Copy all:", numbers[:])           # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# With step
print("Every 2nd:", numbers[::2])       # [0, 2, 4, 6, 8]
print("Every 3rd:", numbers[::3])       # [0, 3, 6, 9]

# Negative step (reverse!)
print("Reversed:", numbers[::-1])       # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# Negative indices in slicing
print("Last 3:", numbers[-3:])          # [7, 8, 9]
print("All except last 2:", numbers[:-2]) # [0, 1, 2, 3, 4, 5, 6, 7]
Output
First 3 items: [0, 1, 2]
Items 3-6: [3, 4, 5, 6]
First 5: [0, 1, 2, 3, 4]
From index 5: [5, 6, 7, 8, 9]
Copy all: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Every 2nd: [0, 2, 4, 6, 8]
Every 3rd: [0, 3, 6, 9]
Reversed: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Last 3: [7, 8, 9]
All except last 2: [0, 1, 2, 3, 4, 5, 6, 7]

โœ๏ธ Modifying Lists

4.4

โž• Adding Items

Python From Source
# Adding items from Session 4
fruits = ["apple", "banana"]
print("Original:", fruits)

# append() - Add to end
fruits.append("cherry")
print("After append:", fruits)

# insert() - Add at specific position
fruits.insert(1, "blueberry")  # Insert at index 1
print("After insert at 1:", fruits)

# extend() - Add multiple items
fruits.extend(["date", "elderberry"])
print("After extend:", fruits)

# Using + operator
more_fruits = fruits + ["fig", "grape"]
print("Combined:", more_fruits)
Output
Original: ['apple', 'banana']
After append: ['apple', 'banana', 'cherry']
After insert at 1: ['apple', 'blueberry', 'banana', 'cherry']
After extend: ['apple', 'blueberry', 'banana', 'cherry', 'date', 'elderberry']
Combined: ['apple', 'blueberry', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'grape']
๐Ÿ’ก append() vs extend()

append(item) adds ONE item (can be a list!)

extend(list) adds EACH item from the list separately

4.5

โž– Removing Items

Python From Source
# Removing items from Session 4
numbers = [1, 2, 3, 4, 5, 3, 6]
print("Original:", numbers)

# remove() - Remove first occurrence of value
numbers.remove(3)  # Removes first 3
print("After remove(3):", numbers)

# pop() - Remove and return item at index
removed = numbers.pop(2)  # Remove item at index 2
print("Popped:", removed)
print("After pop(2):", numbers)

# pop() without index removes last item
last = numbers.pop()
print("Popped last:", last)
print("After pop():", numbers)

# del - Delete by index
del numbers[0]
print("After del [0]:", numbers)

# clear() - Remove all items
numbers.clear()
print("After clear():", numbers)
Output
Original: [1, 2, 3, 4, 5, 3, 6]
After remove(3): [1, 2, 4, 5, 3, 6]
Popped: 4
After pop(2): [1, 2, 5, 3, 6]
Popped last: 6
After pop(): [1, 2, 5, 3]
After del [0]: [2, 5, 3]
After clear(): []
4.6

๐Ÿ”„ Modifying Items

Python From Source
# Modifying items from Session 4
colors = ["red", "green", "blue"]
print("Original:", colors)

# Change single item
colors[1] = "yellow"
print("After changing index 1:", colors)

# Change multiple items with slicing
colors[0:2] = ["purple", "orange"]
print("After slice replacement:", colors)

# Replace with different number of items
colors[1:2] = ["pink", "brown", "gray"]
print("Replaced 1 with 3:", colors)
Output
Original: ['red', 'green', 'blue']
After changing index 1: ['red', 'yellow', 'blue']
After slice replacement: ['purple', 'orange', 'blue']
Replaced 1 with 3: ['purple', 'pink', 'brown', 'gray', 'blue']

๐Ÿ› ๏ธ List Methods

4.7

๐Ÿ“Š Sorting and Reversing

Python From Source
# Sorting from Session 4
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("Original:", numbers)

# sort() - Sorts in place (changes original)
numbers.sort()
print("Sorted ascending:", numbers)

numbers.sort(reverse=True)
print("Sorted descending:", numbers)

# sorted() - Returns new sorted list (original unchanged)
original = [5, 2, 8, 1]
new_sorted = sorted(original)
print("Original unchanged:", original)
print("New sorted list:", new_sorted)

# reverse() - Reverses in place
letters = ['a', 'b', 'c', 'd']
letters.reverse()
print("Reversed:", letters)
Output
Original: [3, 1, 4, 1, 5, 9, 2, 6]
Sorted ascending: [1, 1, 2, 3, 4, 5, 6, 9]
Sorted descending: [9, 6, 5, 4, 3, 2, 1, 1]
Original unchanged: [5, 2, 8, 1]
New sorted list: [1, 2, 5, 8]
Reversed: ['d', 'c', 'b', 'a']
4.8

๐Ÿ”Ž Searching and Counting

Python From Source
# Searching and counting from Session 4
fruits = ["apple", "banana", "cherry", "banana", "date"]

# index() - Find position of first occurrence
position = fruits.index("cherry")
print("'cherry' is at index:", position)

# count() - Count occurrences
banana_count = fruits.count("banana")
print("'banana' appears:", banana_count, "times")

# Check if item exists with 'in'
print("'apple' in list:", "apple" in fruits)
print("'grape' in list:", "grape" in fruits)

# Get min, max, sum
numbers = [5, 2, 8, 1, 9]
print("Min:", min(numbers))
print("Max:", max(numbers))
print("Sum:", sum(numbers))
Output
'cherry' is at index: 2
'banana' appears: 2 times
'apple' in list: True
'grape' in list: False
Min: 1
Max: 9
Sum: 25
4.9

๐Ÿ“‹ Copying Lists

Python From Source
# Copying lists from Session 4

# WRONG way - creates a reference, not a copy!
original = [1, 2, 3]
wrong_copy = original  # Same list, different name!
wrong_copy.append(4)
print("Original (also changed!):", original)

# RIGHT ways to copy
original = [1, 2, 3]

# Method 1: copy()
copy1 = original.copy()

# Method 2: list()
copy2 = list(original)

# Method 3: slicing
copy3 = original[:]

# Modify copies - original stays same
copy1.append(100)
print("Original (unchanged):", original)
print("Modified copy:", copy1)
Output
Original (also changed!): [1, 2, 3, 4]
Original (unchanged): [1, 2, 3]
Modified copy: [1, 2, 3, 100]
โš ๏ธ Shallow vs Deep Copy

The methods above create shallow copies. For nested lists, use import copy and copy.deepcopy()!

๐Ÿ”’ Tuples

4.10

๐Ÿ“ฆ Immutable Sequences

A tuple is like a list, but it's immutable (cannot be changed after creation). Use parentheses () instead of brackets [].

๐Ÿ†š List vs Tuple

    LIST [1, 2, 3]        vs        TUPLE (1, 2, 3)
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    โœ… Can add items                 โŒ Can't add
    โœ… Can remove items              โŒ Can't remove
    โœ… Can modify items              โŒ Can't modify
    ๐Ÿ“ Uses more memory              ๐Ÿ’พ Uses less memory
    ๐Ÿข Slightly slower               ๐Ÿ‡ Slightly faster
    
    Use LIST when you need to change data
    Use TUPLE when data should stay fixed
          
Python From Source
# Tuple basics from Session 4

# Creating tuples
point = (3, 4)           # x, y coordinates
colors = ("red", "green", "blue")
single = (42,)          # Single item tuple - needs comma!
empty = ()              # Empty tuple

print("Point:", point)
print("Colors:", colors)
print("Single:", single)
print("Type of single:", type(single))

# Accessing elements (same as lists)
print("First color:", colors[0])
print("Last color:", colors[-1])
print("Slice:", colors[1:])

# Tuple packing and unpacking
packed = 1, 2, 3        # Parentheses optional!
print("Packed:", packed)

a, b, c = packed       # Unpacking
print("Unpacked: a=", a, "b=", b, "c=", c)
Output
Point: (3, 4)
Colors: ('red', 'green', 'blue')
Single: (42,)
Type of single: <class 'tuple'>
First color: red
Last color: blue
Slice: ('green', 'blue')
Packed: (1, 2, 3)
Unpacked: a= 1 b= 2 c= 3

๐Ÿ”„ Tuple Methods and Operations

Python From Source
# Tuple methods from Session 4
numbers = (1, 2, 3, 2, 4, 2)

# count() - Count occurrences
print("Count of 2:", numbers.count(2))

# index() - Find position
print("Index of 3:", numbers.index(3))

# len(), min(), max(), sum() work too
print("Length:", len(numbers))
print("Max:", max(numbers))

# Convert between list and tuple
my_list = [1, 2, 3]
my_tuple = tuple(my_list)
back_to_list = list(my_tuple)
print("List to tuple:", my_tuple)
print("Tuple to list:", back_to_list)
Output
Count of 2: 3
Index of 3: 2
Length: 6
Max: 4
List to tuple: (1, 2, 3)
Tuple to list: [1, 2, 3]

๐Ÿ“ฆ Nested Lists (2D Arrays)

4.11

๐ŸŽฎ Lists Inside Lists

You can put lists inside lists to create grids, tables, or matrix-like structures!

๐ŸŽฏ 2D List Visualization

    matrix = [
        [1, 2, 3],    โ† Row 0
        [4, 5, 6],    โ† Row 1
        [7, 8, 9]     โ† Row 2
    ]
    
    Access: matrix[row][column]
    
         Col 0  Col 1  Col 2
           โ†“      โ†“      โ†“
    Row 0 [1]    [2]    [3]
    Row 1 [4]    [5]    [6]
    Row 2 [7]    [8]    [9]
    
    matrix[1][2] = 6  (Row 1, Col 2)
          
Python From Source
# Nested lists from Session 4

# Create a 3x3 matrix
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# Access elements
print("First row:", matrix[0])
print("Element at row 1, col 2:", matrix[1][2])

# Loop through nested list
print("\\nPrint matrix:")
for row in matrix:
    for item in row:
        print(item, end=" ")
    print()  # New line after each row

# Modify nested element
matrix[1][1] = 99
print("\\nAfter modification:", matrix[1])
Output
First row: [1, 2, 3]
Element at row 1, col 2: 6

Print matrix:
1 2 3 
4 5 6 
7 8 9 

After modification: [4, 99, 6]

๐Ÿ” Looping Through Lists

4.12

๐ŸŽข Different Loop Styles

Python From Source
# Looping through lists from Session 4
fruits = ["apple", "banana", "cherry"]

# Method 1: Loop through items directly
print("Method 1 - Direct:")
for fruit in fruits:
    print(f"  I like {fruit}")

# Method 2: Loop with index using range()
print("\\nMethod 2 - With index:")
for i in range(len(fruits)):
    print(f"  Index {i}: {fruits[i]}")

# Method 3: enumerate() - best of both worlds!
print("\\nMethod 3 - Enumerate:")
for index, fruit in enumerate(fruits):
    print(f"  {index}: {fruit}")

# enumerate with custom start
print("\\nWith custom start (1):")
for num, fruit in enumerate(fruits, start=1):
    print(f"  #{num}: {fruit}")
Output
Method 1 - Direct:
  I like apple
  I like banana
  I like cherry

Method 2 - With index:
  Index 0: apple
  Index 1: banana
  Index 2: cherry

Method 3 - Enumerate:
  0: apple
  1: banana
  2: cherry

With custom start (1):
  #1: apple
  #2: banana
  #3: cherry

๐Ÿ“‹ Quick Reference

๐Ÿ“ List Methods

Method Description Example
append() Add to end list.append(x)
insert() Add at index list.insert(i, x)
extend() Add multiple items list.extend([a,b])
remove() Remove by value list.remove(x)
pop() Remove by index list.pop(i)
sort() Sort in place list.sort()
reverse() Reverse in place list.reverse()
index() Find position list.index(x)
count() Count occurrences list.count(x)
copy() Shallow copy list.copy()
clear() Remove all list.clear()

๐Ÿšซ Common Mistakes (Lists)

๐Ÿ’ญ Short reflection

In one sentence: why does list.append(x) change the list in place instead of returning a new list?

โœ… CORE (Must know)

๐Ÿ“š NON-CORE (Good to know)

Complete code from course notebook: 4_Python_Data_Structures_(1)_(1) (2).ipynb

Every line of code from the course notebook (verbatim).

# --- Code cell 1 ---
# data types---numerical data types-int,float and complex and string and string methods
# Control stat(loops)and conditional stat(if,else and elif)

# --- Code cell 2 ---
# sequentail data types---list and list methods

# --- Code cell 4 ---
# seq--string,list and tuple

Exploratory Data Analysis--pandas and matplotlib and seaborn

# --- Code cell 6 ---
list1=[]
type(list1)

# --- Code cell 7 ---
king=[123,"gold",7+7j,456.677,"silver",2345,9765.99,123]

# --- Code cell 8 ---
king[4]

# --- Code cell 9 ---
king[4]="platinum"

# --- Code cell 10 ---
king

# --- Code cell 11 ---
len(king)
print(type(king))

# --- Code cell 12 ---
# list can store data of various types
data = ["rahul",256+6j,47.667,5456,1.0, 2.8,"name",256+6j]
print(data)
print(type(data))

# --- Code cell 14 ---
data =     ["rahul",256+6j,47.667,5456,1.0, 2.8,"name",256+6j]
#+ve index--    0      1      2      3.........
#-ve index                              .... -3   -2     -1

# --- Code cell 15 ---
data[-5]

# --- Code cell 16 ---
data[1]

# --- Code cell 17 ---
data

# --- Code cell 19 ---
data[1:4]

# --- Code cell 20 ---
data[3:6:1]

# --- Code cell 21 ---
data

# --- Code cell 22 ---
data[-2:-5:1]

# --- Code cell 23 ---
data[-2:-5:-1]
#data[-2:-5:1]
#data[-2:-5:]

# --- Code cell 24 ---
data

# --- Code cell 25 ---
data[1::2]

# --- Code cell 26 ---
start=start======-2
step1=start+step==-2+(-1)=-3
step2=step1+step=-3+(-1)=-4
step3=step2+step=-4+(-1)=-5
step4=step3+step=1+(1)=2

# --- Code cell 27 ---
data[4:7]

# --- Code cell 28 ---
data[1:4:1]

# --- Code cell 29 ---
data[:5]

# --- Code cell 30 ---
king

# --- Code cell 31 ---
king[2]

# --- Code cell 32 ---
king[4]

# --- Code cell 33 ---
king[-4]

# --- Code cell 34 ---
king[-6]

# --- Code cell 35 ---
king2d = [
    [123, "gold", 7+7j],
    [456.677, "silver", 2345],
    [9765.99, 123]
]

# --- Code cell 36 ---
king2d[1][1]

# --- Code cell 37 ---
data

# --- Code cell 38 ---
data[-6:-9:-1]

# --- Code cell 39 ---
data[::2]

# --- Code cell 40 ---
data[0:3:1]

# --- Code cell 41 ---
data[:3:]

# --- Code cell 42 ---
data[2:6:1]

# --- Code cell 43 ---
data[-2,-3]

# --- Code cell 44 ---
data[0:len(data):2]

# --- Code cell 45 ---
data[0:8:2]

# --- Code cell 46 ---
data

# --- Code cell 47 ---
data[-5:-9:-1]

# --- Code cell 48 ---
data[-2:-5:-1]

# --- Code cell 49 ---
start=start:-5
step1=start+step=-5+(-1)=-6
step2=step1+step=-6+(-1)=-7
step3=step2+step=-7+(-1)=-8
step4=step3+step=-8+(-1)=-9

# --- Code cell 50 ---
a = [1,2,3]

# --- Code cell 51 ---
b = a

# --- Code cell 52 ---
c = a[:]

# --- Code cell 53 ---
id(c)

# --- Code cell 54 ---
id(b)

# --- Code cell 55 ---
id(a)

# --- Code cell 56 ---
data[-5]

# --- Code cell 57 ---
data.index(5480)

# --- Code cell 58 ---
len(data)

# --- Code cell 59 ---
data[:2:1]

# --- Code cell 60 ---
data[2:5:1]

# --- Code cell 61 ---
data_list = ["data", "science", "machine", "learning"]
for j in data_list:
  print(j)

# --- Code cell 62 ---
data_list = ["data", "science", "machine", "learning"]

if "science1" in data_list:
  print("Found, 'science' in the data list")
else:
  print("not availavle")

# --- Code cell 65 ---
data_list = ["data", "science", "machine", "learning"]
data_list.insert(2, "maths")
print(data_list)

# --- Code cell 66 ---
data_list[2]="social"  # substuting/changing

# --- Code cell 67 ---
data_list

# --- Code cell 68 ---
data_list = ["data", "science", "machine", "learning"]
data_list.insert(2, "maths")

# --- Code cell 69 ---
list_var = [1,2,3, "some data"]
list_var.insert(5,"one more")
print(list_var)

# --- Code cell 73 ---
lst = [1,2,3]
lst.insert(2, 99)
lst

# --- Code cell 75 ---
data_list = ["data", "science", "machine", "learning"]
data_list.append("maths")
print(data_list)

# --- Code cell 76 ---

# adding multiple elements  using extend
nums = [1, 2]
nums.extend([3, 4,"new"])
print(nums)

# --- Code cell 77 ---
#adding two lists using +--concadination

data_list = ["data", "science", "machine", "learning","great",455]
science = ['lr',"hello"]

data_list1 = data_list + science
print(data_list1)

# --- Code cell 79 ---

data_list = ["data", "science", "machine", "learning","machine"]
data_list.remove("machine")
print(data_list)

# --- Code cell 81 ---
fruits=["apple","banana","grapes"]
fruits.index("banana")

# --- Code cell 82 ---
data_list = ["data", "science", "machine", "learning"]
data_list.index("machine")

# --- Code cell 84 ---
data_list = ["data", "science", "machine", "learning"]
data_list.pop(1)
data_list

# --- Code cell 85 ---
# removing multiple elements
letters = ['a', 'b', 'c', 'd', 'e']
for item in ["b","d"]:
  letters.remove(item)
print(letters)

# --- Code cell 86 ---
list1=[5,1,4,2]
sorted(list1)
list1

# --- Code cell 87 ---
#removing multiple elements using indexing
letters = ['a', 'b', 'c', 'd', 'b']
indexes_to_remove = [4,3,2,1]
for i in sorted(indexes_to_remove, reverse=True):
    letters.pop(i)
print(letters)

# --- Code cell 88 ---
#removing multiple elements using indexing without sorted

a= ['a', 'b', 'c', 'd', 'b']
for i in a[:]:
  if i == 'b' :
    a.remove(i)
print(a)

# --- Code cell 89 ---
data_list = ["data", "science", "machine", "learning"]
data_list.pop(2)
data_list

# --- Code cell 90 ---
list2=[]
list2.pop()

# --- Code cell 91 ---

data_list = ["data", "science", "machine", "learning"]
data_list.pop(2)
print(data_list)

data_list.pop()
print(data_list)

# --- Code cell 92 ---
data_list = ["data", "science", "machine", "learning"]
data_list.append("maths")
data_list.pop(2)
print(data_list)

# --- Code cell 93 ---
fruits = ["apple", "banana", "cherry", "grape"]
fruits.pop(3)

# --- Code cell 94 ---
fruits = ["apple", "banana", "cherry"]
del fruits  # Deletes the entire list
# print(fruits)  # โŒ This will cause an error (list no longer exists)
fruits

# --- Code cell 95 ---
fruits = ["apple", "banana", "cherry", "grape"]
del fruits
print(fruits)

# --- Code cell 97 ---

data_list = ["data", "science", "machine", "learning"]
del(data_list[0])
print(data_list)

# --- Code cell 98 ---
data_list = ["data", "science", "machine", "learning"]
data_list[0] = "learning"
data_list[3] = "data"
print(data_list)

# --- Code cell 99 ---
del (data_list) # Delete complete list
#print(data_list)

# --- Code cell 101 ---
data_list = ["data", "science", "machine", "learning"]
data_list.clear() # clear the elements from list
print(data_list)

# --- Code cell 103 ---
#sort list
data = [100, 62, 84, 75, 105.0, 72.8]
data.sort() # by defult its ascending order
print(data)

# --- Code cell 104 ---
data.sort(reverse = True) # to get descending order
print(data)

# --- Code cell 106 ---
nums=[2,5,7,1]
nums.sort()
nums

# --- Code cell 107 ---
nums=[2,5,7,1]
sorted(nums)

# --- Code cell 109 ---
#### #copies content from one list to another
import copy
data_list = ["data", "science", "machine", "learning"]
science_list = copy.deepcopy(data_list )
#print(science_list)

data_list.pop()
print(science_list)
print(data_list)
print(id(data_list))
print(id(science_list))

# --- Code cell 111 ---
import copy

# Original nested list
flights = [["AI102", "EK505"], ["QR720", "SQ321"]]

# Shallow copy
shallow_copy = copy.copy(flights)

# Modify inner list
shallow_copy[0][1] = "LH760"

print("Original:", flights)
print("Shallow Copy:", shallow_copy)
print(id(flights[0][1]))
print(id(shallow_copy[0][1]))

# --- Code cell 112 ---
#count and index methods on list
data_list = ["science","data", "science", "machine", "learning","science"]
print("count of word: ", data_list.count("science"))

# --- Code cell 113 ---

print("word found at index: ", data_list.index("science"))

# --- Code cell 115 ---
# -----------------------------------
# Step 1: Start of shift โ€“ no flights in queue
# -----------------------------------
landing_queue = []                     # list creation

# --- Code cell 116 ---
# -----------------------------------
# Step 2: Flights enter the landing queue
# -----------------------------------
landing_queue.append("AI202")          # append
landing_queue.append("BA450")
landing_queue.append("EK713")

# --- Code cell 117 ---
print("Initial Queue:", landing_queue)

# --- Code cell 118 ---
# -----------------------------------
# Step 3: Emergency flight enters (highest priority)
# -----------------------------------
landing_queue.insert(0, "EM999")       # insert at beginning
print("After Emergency Flight:", landing_queue)

# --- Code cell 119 ---
# -----------------------------------
# Step 4: Flight information update
# Example: BA450 becomes BA450D (diverted routing)
# -----------------------------------
index = landing_queue.index("BA450")   # search
landing_queue[index] = "BA450D"        # modify
print("After Update:", landing_queue)

# --- Code cell 120 ---
# -----------------------------------
# Step 5: Flight decides to divert to another airport
# -----------------------------------
landing_queue.remove("EK713")          # remove
print("After Diversion:", landing_queue)

# --- Code cell 121 ---
nested = [[1, 2], [1, 2], [3, 4]]
nested.count([1, 2])

# --- Code cell 122 ---
nested.count(1)

# --- Code cell 123 ---
# -----------------------------------
# Step 6: ATC clears the next flight to land
# -----------------------------------
next_landing = landing_queue.pop(0)    # pop (first item)
print("Cleared to Land:", next_landing)
print("Remaining Queue:", landing_queue)

# --- Code cell 124 ---
#VIP aircraft from government arrives and must take off first
landing_queue.insert(0, "VIP001")

# --- Code cell 125 ---
# -----------------------------------
# Step 5: Flight decides to divert to another airport
# -----------------------------------
landing_queue.remove("VIP001")          # remove
print("After Diversion:", landing_queue)

# --- Code cell 126 ---
# -----------------------------------
# Step 7: Multiple new inbound flights detected
# -----------------------------------
landing_queue.extend(["QR550", "LH330"])   # extend
print("After New Flights:", landing_queue)

# --- Code cell 127 ---
# -----------------------------------
# Step 8: View last flight in queue
# -----------------------------------
print("Last in Queue:", landing_queue[-1])

# --- Code cell 128 ---
# -----------------------------------
# Step 9: Sort by flight number for administrative review
# -----------------------------------
landing_queue.sort()
print("Sorted Queue:", landing_queue)

# --- Code cell 129 ---
# -----------------------------------
# Step 10: Reverse list for runway reallocation plan
# -----------------------------------
landing_queue.reverse()
print("Reversed Queue:", landing_queue)

# --- Code cell 130 ---
# -----------------------------------
# Step 11: Count duplicate flights (rare but possible)
# -----------------------------------
landing_queue.append("QR550")          # cargo entry
print("QR550 Count:", landing_queue.count("QR550"))

# --- Code cell 131 ---
# -----------------------------------
# Step 12: Make a copy before resetting the system
# -----------------------------------
backup_queue = landing_queue.copy()
print("Backup Queue:", backup_queue)

# --- Code cell 132 ---
# -----------------------------------
# Step 13: Clear queue at the end of shift
# -----------------------------------
landing_queue.clear()
print("End of Shift Queue:", landing_queue)

# --- Code cell 133 ---
help(list)

# --- Code cell 135 ---
ren=()
type(ren)

# --- Code cell 136 ---
data_tuple = ("data", "science", "machine", "learning")
print(data_tuple)
print(type(data_tuple))

# --- Code cell 137 ---
data_tuple[1]="maths"

# --- Code cell 138 ---
data_tuple[::-1]

# --- Code cell 139 ---
data_tuple[0:3]

# --- Code cell 141 ---
data_tuple[0] = 'engineer' # this wont work

# --- Code cell 142 ---
data_tuple = list(data_tuple)

# --- Code cell 143 ---
data_tuple

# --- Code cell 144 ---
  #  workaround to update tuple
data_tuple[0] = 'engineer'
data_tuple

# --- Code cell 145 ---
data_tuple = tuple(data_tuple)
print(data_tuple)
print(type(data_tuple))

# --- Code cell 146 ---
data_tuple.remove("machine")

# --- Code cell 147 ---
#adding item to tuple
data_tuple = ("data", "science", "machine", "learning")
addition = ("maths")
data_tuple += addition # data_tuple = data_tuple + addition
type(addition)
# if single is given it takes as a str

# --- Code cell 148 ---
#adding item to tuple
data_tuple = ("data", "science", "machine", "learning")
addition = ("maths",)
data_tuple1 = data_tuple + addition

# --- Code cell 149 ---
#adding item to tuple
data_tuple = ("data", "science", "machine", "learning")
addition = ["maths",]
data_tuple1 = data_tuple + addition

# --- Code cell 150 ---
#adding item to tuple
data_tuple = ("data", "science", "machine", "learning")
addition = ("maths",)
data_tuple += addition # data_tuple = data_tuple + addition
data_tuple

# --- Code cell 151 ---
#items cannot be removed from tuple
#conversion to list is workaround
data_tuple = ("data", "science", "machine", "learning")
data_tuple = list(data_tuple)
data_tuple.remove("science")
data_tuple = tuple(data_tuple)
data_tuple

# --- Code cell 152 ---
data_tuple

# --- Code cell 153 ---
#for loop on tuple
for x in data_tuple:
  print(x)

# --- Code cell 154 ---
days_of_week = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
print(days_of_week[0])  # Output: Monday

# --- Code cell 156 ---
follow={2}  # an empty curly braces called dict,if a valued filled then called as set.
type(follow)

# --- Code cell 157 ---
list11=[3,5,3,7,8,2,9,2,88,11,11]

# --- Code cell 158 ---
set(list11)

# --- Code cell 159 ---
list(set(list11))

# --- Code cell 160 ---
data_set = {"data", "science", "machine", "learning"}
print(data_set)
print(type(data_set))

# --- Code cell 161 ---
a = {"data", "science", "machine", "learning","science"}

# --- Code cell 162 ---
a

# --- Code cell 163 ---
a[0]

# --- Code cell 164 ---
list1=[4,3,4,5,6,6,7,6]
set1=set(list1)
set1

# --- Code cell 165 ---
#sets do not hold duplicate values

data_set = {"data", "science", "machine", "learning", "science"}
print(data_set)

# --- Code cell 166 ---
print(data_set[1]) # sets are unordered, cannot be accessed by index

# --- Code cell 167 ---
#iterating over set
data_set = {"data", "science", "machine", "learning","data"}

for value in data_set:
  print(value)

# --- Code cell 168 ---
data_set = {"data", "science", "machine", "learning"}
if "science" in data_set:
  print("yes")
else:
  print("no")

# --- Code cell 170 ---

data_set = {"data", "science", "machine", "learning"}

data_set.add("maths")

data_set

# --- Code cell 171 ---
evens = set(range(0, 21, 2))
print(evens)

# --- Code cell 173 ---
data_set = {"data", "science", "machine", "learning",None}
data_set.pop()
data_set

# --- Code cell 174 ---
# Add two sets
data_set = {"data", "science", "machine", "learning"}
machine_set = {"lr", "svm", "kmeans"}

data_set.update(machine_set)
data_set

# --- Code cell 176 ---

data_set = {"data", "science", "machine", "learning"}

data_set.remove("machine1")

print(data_set)

# --- Code cell 178 ---
data_set

# --- Code cell 179 ---

data_set.pop()

print(data_set)

# --- Code cell 180 ---
unique_visitors = set()
unique_visitors.add("192.168.1.1")
unique_visitors.add("192.168.1.2")
unique_visitors.add("192.168.1.1")  # Duplicate ignored

print(unique_visitors)  # Output: {'192.168.1.1', '192.168.1.2'}

# --- Code cell 182 ---
# union()

# Combine elements from sets (no duplicates).
a = {1, 2}
b = {2, 3}
print(a.union(b))

# --- Code cell 183 ---
# intersection()

# Common elements.
a = {1, 2, 3}
b = {2, 3, 4}
print(a.intersection(b))

# --- Code cell 184 ---
# difference()

# Elements in set A but not in B.
a = {1, 2, 3}
b = {2, 4}
print(a.difference(b))

# --- Code cell 186 ---
dictionary = {
              "company": "Inttrvu",
              "website": "Inttrvu.ai",
              "year": 2023,
              "type": "Edtech",
              "city": "Pune"
            }

print(dictionary)

# --- Code cell 187 ---
dictionary[0]

# --- Code cell 188 ---
print(list(dictionary)[0])

# --- Code cell 189 ---
dictionary["company"]

# --- Code cell 190 ---
list(dictionary)

# --- Code cell 191 ---
dictionary.keys()  #get all keys

# --- Code cell 192 ---
dictionary.values() #get all values

# --- Code cell 193 ---
dictionary.items() # to get all the comb

# --- Code cell 194 ---
print(dictionary.get("company")) # get value of specific key

# --- Code cell 195 ---
dictionary

# --- Code cell 196 ---
dictionary["city"]= "bangalore"  # change value of dictionary key
dictionary

# --- Code cell 197 ---
#Add new item to dictionary
dictionary["course"]= "data_science"
dictionary

# --- Code cell 198 ---
dictionary.update({"city": "Pune","year":2025}) # change value of dictionary key
dictionary

# --- Code cell 199 ---
dictionary.update({"location": "Mumbai"}) # if this key is not present then it would be added , if found value if overwritten
dictionary

# --- Code cell 200 ---
dictionary.update({"country": "India"}) # if this key is not present then it would be added , if found value if overwritten
dictionary

# --- Code cell 201 ---
# Duplicate keys are not allowed

dictionary = {
              "company": "Inttrvu",
              "website": "Inttrvu.ai",
              "year": 2023,
              "type": "Edtech",
              "city": "Pune",
              "city": "Mumbai"
            }

print(dictionary)

# --- Code cell 202 ---
# Delete specific key value pair

dictionary.pop("city")
print(dictionary)

# --- Code cell 203 ---
dictionary.items()

# --- Code cell 204 ---
# Looping through keys and values of dictionary

for k, v in dictionary.items():
  print(k, v)

# --- Code cell 205 ---
for k in dictionary.keys(): # Looping through only keys
  print(k)

# --- Code cell 206 ---
for v in dictionary.values(): # Looping through only values
  print(v)

# --- Code cell 208 ---
# -------------------------------------------------------
# Restaurant table availability (SET)
# -------------------------------------------------------
available_tables = {1, 2, 3, 4, 5}   # Table numbers

# --- Code cell 209 ---
# -------------------------------------------------------
# Booked table details (DICTIONARY)
# table_number : customer_name
# -------------------------------------------------------
bookings = {}

print("Initial Available Tables:", available_tables)

# --- Code cell 210 ---
# -------------------------------------------------------
# 1. Customer books a table
# -------------------------------------------------------
customer = "Arjun"
book_table = 3

if book_table in available_tables:
    bookings[book_table] = customer          # add to dictionary
    available_tables.discard(book_table)     # remove from available
    print(f"\nTable {book_table} booked for {customer}")
else:
    print(f"\nTable {book_table} is not available.")

# --- Code cell 211 ---
# -------------------------------------------------------
# 2. Another customer books a table
# -------------------------------------------------------
customer2 = "Priya"
book_table2 = 1

if book_table2 in available_tables:
    bookings[book_table2] = customer2
    available_tables.discard(book_table2)
    print(f"Table {book_table2} booked for {customer2}")
else:
    print(f"Table {book_table2} is not available.")

print("\nAvailable Tables:", available_tables)
print("Current Bookings:", bookings)

# --- Code cell 212 ---
# -------------------------------------------------------
# 3. Customer cancels a booking
# -------------------------------------------------------
cancel_table = 3

if cancel_table in bookings:
    cancelled_customer = bookings[cancel_table]
    del bookings[cancel_table]               # remove customer from dictionary
    available_tables.add(cancel_table)       # add table back to availability
    print(f"\nBooking cancelled for {cancelled_customer} at table {cancel_table}")
else:
    print("\nNo booking found at that table.")

print("\nAvailable Tables after cancellation:", available_tables)
print("Bookings after cancellation:", bookings)

# --- Code cell 213 ---
# -------------------------------------------------------
# 4. Checking fully booked or not
# -------------------------------------------------------
if len(available_tables) == 0:
    print("\nRestaurant is fully booked.")
else:
    print("\nTables still available:", available_tables)

# --- Code cell 214 ---
# -------------------------------------------------------
# 5. Print all customers seated
# -------------------------------------------------------
print("\n customers currently seated:")
for table, customer in bookings.items():
    print(f"Table {table}: {customer}")