0% found this document useful (0 votes)
4 views45 pages

? Python Beginner Notes mine

This document provides beginner notes on Python, covering core data types, variables, user input, arithmetic operators, and string methods. It also explains collections like lists and tuples, their operations, and the differences between them. Additionally, it includes details on loops, conditional statements, and common errors in Python programming.

Uploaded by

smritispam2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views45 pages

? Python Beginner Notes mine

This document provides beginner notes on Python, covering core data types, variables, user input, arithmetic operators, and string methods. It also explains collections like lists and tuples, their operations, and the differences between them. Additionally, it includes details on loops, conditional statements, and common errors in Python programming.

Uploaded by

smritispam2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 45

🐍 Python Beginner Notes

✅ Core Data Types

1. int (Integer)
o Any whole number without a decimal.
o Examples: 2, 3, -9, 3700, -102.
o As long as no decimal is present, it is considered an
integer.
2. float
o Any number with a decimal point.
o Examples: 2.0, 9.7, 0.0, -3.14.
o Even 2.0 is a float due to the .0.
3. str (String)
o A sequence of characters/numbers inside quotes.
o Can use either ' ' or " " — both are equivalent.
o Examples:
 "hello", 'hello', "4.6"

 "4.6" is a string, not a float, because it's


quoted.
o To include quotes inside a string:
 '\"Hello\"' → Wrap in single quotes.
 "\'World\'" → Wrap in double quotes.
4. bool (Boolean)
o Represents True or False.
o Can be seen as 1 (True) or 0 (False).
o Examples: True, False.
Output and Printing

print() Function

 Used to display output to the console.


 Example:
print("Hello, world")

Printing Rules:

 Strings must be inside quotes.


 Numbers like 4.5 can be printed directly (recognized as float).

Print Multiple Values:


print(4.5, "hello", False)
# Output: 4.5 hello False

Custom end Parameter:

 By default, print() ends with a newline (\n).


 You can change it:
print("Hello", end="|")
print("World")
# Output: Hello|World

🔤 Variables

Assigning Variables:
x = 10
name = "Tim"

Printing Variables:
print(x) # Output: 10
print(name) # Output: Tim

Dynamic Typing & Multiple Assignments:


n=0 # int
n = "abc" # str
n, m = 0, "abc"
n, m, z = 0.125, "abc", False

Increment:
n += 1 # Correct
n++ # ❌ Invalid in Python

Variable Naming Rules:

 Must start with a letter or underscore.


 Cannot start with a number.
 Cannot contain special characters except _.
 Valid: hello_world, _var32, num1.
 Invalid: 9hello, hello$, #name.

Naming Conventions:

 Use snake_case (e.g., hello_world).


 Avoid camelCase (common in Java/JS).

⌨️User Input

Getting Input:
input("Prompt: ") # Prompt must be a string.

Store Input in Variable:


name = input("Name: ")
print(name)

Input is Always a String:


age = input("Age: ") # "25" (string)
print("You are", age, "years old")

Convert Input to Number:


num = int(input("Enter a number: "))
print(num - 5)

➕ Arithmetic Operators

Symbo
Operator Description
l

Addition + 9 + 3 → 12

Subtraction - 9-3→6

Multiplication * 9 * 3 → 27

Division / Always returns float (9 / 3 → 3.0)

Floor Division // Returns integer (10 // 3 → 3)

Modulus % Remainder (10 % 3 → 1)

Exponentiation ** Power (3 ** 2 → 9)

Note: Mixed int and float operations result in float.

📌 Data Type Conversion

String to Integer:
num = int(input("Enter a number: "))
print(num - 5)

String to Float:
f = float(input("Enter a float: "))
print(f * 2)

➗ Order of Operations (BEDMAS/PEMDAS)

1. Brackets
2. Exponents
3. Division & Multiplication (left to right)
4. Addition & Subtraction (left to right)

Example:
result = (2 + 3) * 5 ** 2 # Output: 125

⚠️Common Errors

 Mixing incompatible types:


"hello" + 9 # ❌ Error
 Math with string inputs without conversion.

📚 String Methods & Concepts

🔹 What is a Method?

 A method is a function associated with an object.


 Called using dot notation: object.method().
 Example:
"hello".upper() # Makes the string uppercase.

🔹 type() Function

 Checks the data type of a variable.


 Example:
type("hello") # Returns: <class 'str'>

🔹 Common String Methods

Method Description Example Output

Converts all characters to


.upper() "Hello".upper() "HELLO"
uppercase.

Converts all characters to


.lower() "Hello".lower() "hello"
lowercase.

Capitalizes the first


.capitalize() "hello".capitalize() "Hello"
character; rest lowercase.

Counts occurrences of x in
.count(x) "Hello".count("l") 2
the string.

Key Notes:

 Case Sensitivity: Methods are case-sensitive.


"Hello".count("L") # 0 (no uppercase 'L')
"Hello".lower().count("l") # 2 (converted to lowercase)

🔹 Method Chaining

 Combine multiple methods in one line.


 Example:
"Hello World".lower().count("o") # Output: 2

s = "abc"
# Immutable: s[0] = "A" ❌
s += "def" # New string "abcdef"

# ASCII values
print(ord("a")) # 97

# Join list of strings


print(" ".join(["hello", "world"])) # "hello world"

🧮 String Operations

🔹 Concatenation (+)

 Combines strings:
"Hello" + "World" # Output: "HelloWorld"

🔹 Repetition (*)

 Repeats a string:
"Hi" * 3 # Output: "HiHiHi"

🔍 Conditional Operators (Comparisons)

Comparison Operators

Operato
Meaning Example Result
r

== Equal to "a" == "a" True

!= Not equal to "a" != "b" True

< Less than (ASCII comparison) "a" < "b" True

> Greater than "Z" > "a" False

Math Operations
import math

# Division rounding
print(-3 // 2) # -2 (rounds down)
print(int(-3 / 2)) # -1 (rounds toward zero)
# Modulo quirks
print(-10 % 3) # 2 (Python)
print(math.fmod(-10, 3)) # -1.0 (like C++)

# Math utilities
print(math.floor(3 / 2)) # 1
print(math.pow(2, 3)) # 8.0
print(float("inf") > 1e9) # True

String Comparison Rules

 Compares character-by-character using ASCII values:


ord("A") # 65
ord("a") # 97
"a" > "Z" # True (97 > 65)

🔗 Chained Conditionals & Logical Operators

🔹 Boolean Logic

Operato
Description Example Result
r

and True only if both sides are True. True and False False

or True if at least one side is True. True or False True

not Reverses the Boolean value. not True False

Operator Precedence

1. not
2. and
3. or

Examples:
print(True and False) # False
print(not (False or True)) # False

🧠 If / Elif / Else Statements

🔹 Basic Syntax
if condition:
# Code block
elif condition:
# Code block
else:
# Code block

🔹 Key Rules

 Only one if and one else allowed.


 Multiple elif blocks can be used.
 else must come last.

Example:
name = "Tim"
if name == "Tim":
print("You are great")
elif name == "Joe":
print("Bye Joe")
else:
print("No match")

Nested Conditions
if x > 2:
if y < 5:
print("Nested condition")

📘 Python Beginner Notes: Lists and


Tuples
📌 What is a Collection?
 A collection is a group of items/elements.
 Python has various
collections: lists, tuples, sets, dictionaries.
 Focus in this section: Lists and Tuples.

🔹 Lists
✅ What is a List?

 A list is a collection that is:


o Ordered (maintains the order of elements).
o Mutable (can be changed).
o Can hold multiple data types (integers, strings,
booleans, etc.).

🔹 Example:
x = [4, True, "hi"]

✅ Creating a List
x = [4, True, "hi"] # List with elements
x = [] # Empty list

🔧 List Operations

🧮 len() function

 Returns the number of elements in the list (or string, etc.).


len(x) # → 3

➕ append()
 Adds a single element to the end of the list.
x.append("hello") # x becomes [4, True, "hi", "hello"]

➕ extend()

 Adds multiple elements from another list.


x.extend([4, 5, 6]) # Appends 4, 5, 6 to the end

➖ pop()

 Removes and returns the last element if no index is given.


x.pop() # Removes last item
x.pop(0) # Removes item at index 0 (first element)

🔎 Accessing Elements

 Use square brackets [] with an index.


 Indexing starts at 0.
x[0] # First element
x[2] # Third element
x[-1] # Last element

✏️Modifying Elements
x[0] = "hello" # Changes value at index 0 to "hello"

🔁 List Mutability

 Lists are mutable.


 If you assign one list to another (y = x), both variables point to
the same object (reference).
 Changes to one will reflect in the other.
x = [1, 2, 3]
y=x
x[0] = 100
print(y) # → [100, 2, 3]

✅ Creating a Copy of a List (not reference):


y = x[:] # This creates a shallow copy

Now changes in x won't affect y.

🔀 Lists Can Be Nested

 Lists can contain other lists or tuples.


nested_list = [[1, 2], [3, 4]]

🧮 Stack Operations
arr = [1, 2, 3]
arr.append(4) # [1, 2, 3, 4]
arr.pop() # [1, 2, 3]

🔪 Sublists (Slicing)
print(arr[1:3]) # [2, 3] (last index exclusive)
print(arr[0:10]) # No out-of-bounds error!

📦 Unpacking
a, b, c = [1, 2, 3] # a=1, b=2, c=3

🔀 Custom Sort
arr = ["bob", "alice", "jane"]
arr.sort(key=lambda x: len(x)) # Sort by length

📊 2D List (Correct Way)


matrix = [[0] * 4 for _ in range(4)] # 4x4 matrix
🔹 Tuples
✅ What is a Tuple?

 A tuple is similar to a list but:


o Immutable (cannot be changed after creation).
o Ordered.

🔹 Syntax:
x = (1, 2, 3)

🔎 Accessing Elements (Same as list):


x[0] # → 1

🔒 Tuples are Immutable

 Cannot:
o Modify: x[0] = 5 → ❌ Error
o Append: x.append(4) → ❌ Error
o Pop: x.pop() → ❌ Error

❗ You must redefine the tuple to change it.


tup = (1, 2, 3)
# Immutable: tup[0] = 0 ❌

🔑 As Dictionary Keys
myMap = {(1, 2): "value"} # Valid (tuples are hashable)

💡 Tuple Summary

 Tuples are used when data should not change.


 Safer for fixed collections.
 Slightly more memory-efficient than lists.

🔗 Mixed and Nested Collections


 Python allows nesting and mixing types:
x = [1, (2, 3), [4, 5]]
 You can put:
o Tuples inside lists
o Lists inside tuples
o Lists inside lists
o Tuples inside tuples

✅ Summary Table: List vs Tuple


Feature List Tuple

Syntax [1, 2, 3] (1, 2, 3)

Mutabilit
Mutable (can change) Immutable (cannot change)
y

Ordered ✅ Yes ✅ Yes

Methods .append(), .pop() etc. ❌ (None for modifying)

Use Case Dynamic data Static data

🔁 Python Loops: for and while


🔹 FOR LOOP
✅ Purpose

 Used when you know in advance how many times you want
to iterate.
 Often used to iterate over:
o A range of numbers.
o Collections (lists, strings, tuples).

✅ Basic Syntax
for variable in iterable:
# do something

🔹 Example
for i in range(10):
print(i)
# Output: 0 to 9 (10 not included)

🔄 Reverse Loops
for i in range(5, 1, -1): # 5, 4, 3, 2
print(i)

🔹 range() Function
Used to generate a sequence of numbers.

🔧 Syntax
range(start, stop, step)

Argument Description Default

start Starting number 0

stop Up to but not including this number Required


Argument Description Default

step Increment between numbers 1

🔹 Examples
range(10) # 0 to 9
range(1, 10) # 1 to 9
range(1, 10, 2) # 1, 3, 5, 7, 9
range(10, -1, -1) # 10 to 0 (reverse)

⚠️Invalid Range
range(-10, -1, -1) # Does nothing (already past stop condition)

🔁 Looping Through Lists


🔹 Example
x = [3, 4, 5, 6]
for i in x:
print(i)
# Prints all elements in the list.

📍 Accessing by Index with range(len(...))


x = [3, 4, 5, 6]
for i in range(len(x)):
print(x[i])
# Iterates using indexes: 0 to len(x)-1.

🔢 enumerate() Function

Used to access both index and value at the same time.


x = [3, 4, 5, 6]
for i, element in enumerate(x):
print(i, element)

Output:
03
14
25
36

🔁 Summary: for Loop Variants


Style Use Case

for i in range(n) Fixed number of times

for val in list Loop through elements

for i in range(len(x)) Index-based access

for i, val in enumerate(x) Index + value access

🔄 WHILE LOOP
✅ Purpose

 Used when you want to run a loop based on a


condition rather than a set number of times.

✅ Basic Syntax
while condition:
# do something

🔹 Example
i=0
while i < 10:
print("Current run")
i += 1
# Runs until the condition (i < 10) becomes False.

🔁 Increment Variants
i += 1 # Add 1
i *= 2 # Multiply by 2
i /= 2 # Divide by 2

🧨 Infinite Loop with break


🔹 Example
i=0
while True:
i += 1
if i == 10:
break

 Runs infinitely until i == 10, then breaks out of the loop.

🔄 Nested Loop Note

 break only exits the innermost loop.

🔁 Loop Type Comparison


Feature for Loop while Loop

When number of iterations is When looping until a condition


Use Case
known fails

Iterating over collections or


Typical Use Waiting for a condition to fail
ranges

Break on
Yes (using break) Yes
Condition?

Infinite Loop
Rare Common (with while True)
Setup
🔪 Python Slice Operator
✅ What is a Slice?

 A subset of a sequence (lists, strings, tuples)


 Created using square brackets [] with colons :
 Syntax mirrors range() function

📚 General Syntax
python
Copy
Download
sequence[start : stop : step]

Component Meaning Default

start Index to start (inclusive) 0

stop Index to stop (exclusive) len(seq)

step Step size (positive/negative) 1

🔹 Basic Example
x = [0, 1, 2, 3, 4, 5]
x[0:4:2] # Output: [0, 2] (start at 0, stop before 4, step 2)

✅ Partial Slicing

Syntax Meaning Example

x[:4] Start → index 4 [0,1,2,3]

x[2:] Index 2 → end [2,3,4,5]

x[::2] Whole list, step 2 [0,2,4]

x[4:2:-1] Backward from 4 to 2 (exclusive) [4,3]

🔄 Reversing Sequences
x[::-1] # Reverses list → [5,4,3,2,1,0]
s = "hello"
s[::-1] # "olleh"

🔹 String/Tuple Slicing
t = (0,1,2,3,4)
t[1:4:2] # (1,3)

s = "python"
s[1:4] # "yth"

💡 Slice Summary Table

Syntax Description Example Output

x[start:stop] From start to stop-1 x[1:4] → [1,2,3]

x[:stop] Start → stop-1 x[:3] → [0,1,2]

x[start:] Start → end x[2:] → [2,3,4,5]

x[::step] Full sequence with step x[::2] → [0,2,4]

x[::-1] Reversed sequence x[::-1] → [5,4,...,0]

🟩 Python Sets
✅ What is a Set?

 Unordered, unique collection


 No indexing (cannot access by position)
 Extremely fast membership tests

🧱 Creating Sets
s = set() # Empty set (NOT {})
s = {4, 30, 2, 2} # {2, 4, 30} (duplicates auto-removed)

🛠 Core Operations
Operation Method Example

Add element .add() s.add(5)

Remove s.remove(5) (KeyError if


.remove()
element missing)

Check
in operator 4 in s → True
membership

Union .union() or ` ` s1.union(s2)

Intersection .intersection() or & s1 & s2

Difference .difference() or - s1 - s2

🔹 Set Methods Deep Dive


s1 = {1, 2, 3}
s2 = {3, 4, 5}

s1.union(s2) # {1,2,3,4,5}
s1.intersection(s2) # {3}
s1.difference(s2) # {1,2}
s1.symmetric_difference(s2) # {1,2,4,5} (XOR)

⚡ Performance Notes

 Membership test x in set → O(1) (vs O(n) for lists)


 Ideal for duplicate removal:
list(set([1,2,2,3])) # [1,2,3]

🔀 Set Comprehension
{i for i in range(5)} # {0,1,2,3,4}

📌 Key Comparisons
Slice Operator
 Works on lists, strings, tuples
 Never modifies original (returns new object)
 Negative indices supported (x[-3:] → last 3 elements)

Sets

 Cannot store lists/dicts (only hashable types)


 No order → print({1,2,3} may show {2,1,3}
 Frozen sets exist for immutable versions

⚠️Common Pitfalls
{} # Creates dict, not set!
set([[]]) # TypeError: unhashable type
x[1:10] # No error even if sequence shorter than 10

Both features are essential for clean, Pythonic code - slices for
sequence manipulation and sets for efficient uniqueness operations.

🟨 Python Dictionaries
✅ What is a Dictionary?

 Key-value pair collection (similar to hash maps/objects)


 Keys must be immutable (strings, numbers, tuples)
 Values can be any type
 Implemented with hash tables for O(1) lookups

🧱 Creating Dictionaries
x = {"key": 4} # Basic
x = dict(key1=5, key2=6) # Alternate syntax
empty_dict = {} # Empty dictionary

🔍 Core Operations

Operation Syntax Example

Add/Modify dict[key] = value x["new_key"] = 10


Operation Syntax Example

Access dict[key] x["key"] → 4

Check Key Existence key in dict "key" in x → True

Delete Key del dict[key] del x["key"]

Get All Keys .keys() list(x.keys()) → ["key"]

Get All Values .values() list(x.values()) → [4]

Get Key-Value Pairs .items() list(x.items()) → [("key",4)]

🔁 Iterating Over Dictionaries


# Method 1: Key-value pairs
for key, value in x.items():
print(key, value)

# Method 2: Keys only


for key in x:
print(key, x[key])

# Method 3: Values only


for value in x.values():
print(value)

⚡ Dictionary Comprehension
{key_expr: value_expr for item in iterable}

Examples:
{i: i*2 for i in range(3)} # {0:0, 1:2, 2:4}
{k.lower(): v for k,v in {"A":1}.items()} # {"a":1}

⚠️Common Pitfalls
x["missing_key"] # KeyError
x.get("missing_key") # Returns None (safe)
x.get("key", default) # Returns default if missing
🟩 Python Comprehensions
✅ What is a Comprehension?

 One-line syntax for creating collections


 More readable and often faster than loops
 Supported for: lists, dicts, sets, generators

📋 List Comprehension
[expression for item in iterable]

Examples:
[x*2 for x in range(5)] # [0,2,4,6,8]
[x for x in "hello" if x in "aeiou"] # ["e","o"]

📚 Dictionary Comprehension
{key: value for item in iterable}

Example:
{i: str(i) for i in [1,2,3]} # {1:"1", 2:"2", 3:"3"}

🔷 Set Comprehension
{expression for item in iterable}

Example:
{ord(c) for c in "apple"} # {97, 112, 108, 101}

🟣 Generator Expression
(expression for item in iterable)

sum(x*x for x in range(10)) # 285 (memory efficient)

🧠 Advanced Features

Nested Comprehensions
[[i*j for j in range(3)] for i in range(2)]
# [[0,0,0], [0,1,2]]
Conditional Logic
["Even" if x%2==0 else "Odd" for x in range(4)]
# ["Even", "Odd", "Even", "Odd"]

Multiple Iterables
[x+y for x in "abc" for y in "123"]
# ["a1","a2","a3","b1",...,"c3"]

📌 Performance Notes

 Faster than equivalent for loops


 More memory efficient than manual appending
 Avoid nested comprehensions beyond 2 levels for readability

🔑 Key Comparisons
Feature Dictionaries Comprehensions

Primary Use Key-value storage Collection creation

Mutability Mutable Creates new object

Lookup Speed O(1) for keys N/A

Best For Structured data, configurations Transforming/filtering data

Memory
Higher overhead Efficient for one-time operations
Usage

Both dictionaries and comprehensions are essential Python tools -


dictionaries for structured data storage and comprehensions for
elegant data transformations.

Heaps
import heapq
# Min-heap (default)
minHeap = []
heapq.heappush(minHeap, 3)
print(minHeap[0]) # Peek: 3

# Max-heap (workaround)
maxHeap = []
heapq.heappush(maxHeap, -3)
print(-1 * maxHeap[0]) # Peek: 3

Queues (Deque)
from collections import deque
queue = deque()
queue.append(1) # [1]
queue.appendleft(2) # [2, 1]
queue.pop() # [2]

🟪 Python Functions
✅ Defining a Function

 Use the def keyword followed by a name and parentheses:

python

Copy

Download

def func():
# code block
 You can leave the parameters empty or include them
 Code inside the function is indented and only runs when the
function is called

✅ Example:
def func():
print("Run")

func() # Output: Run


 You define the function using def
 You call it using its name followed by ()

🔁 Nested Functions

Python supports functions inside functions:


def outer():
def inner():
print("Inside inner")
inner()

outer()

 Inner function is only accessible from within the outer


function

📦 Functions are Objects

 In Python, functions are actually objects, meaning:


o They can be returned
o They can be passed as parameters
o They can be stored in variables

🧮 Function with Arguments

You can define a function with parameters:


def func(x, y):
print(x)
print(y)

func(5, 6)
# Output: 5
# 6

 Parameters x and y must be passed when calling the function

🔙 Return Values

Use return to return values from the function:


def func(x, y):
return x * y
print(func(5, 6)) # Output: 30

🧵 Returning Multiple Values

Functions can return multiple values, which are returned as


a tuple:
def func(x, y):
return x * y, x / y

print(func(5, 6)) # Output: (30, 0.83333...)

🧩 Unpacking Return Values

You can unpack multiple return values:


r1, r2 = func(5, 6)
print(r1, r2) # Output: 30 0.83333...

 This separates the tuple into individual variables

Optional Parameters (Default Arguments)

You can make parameters optional by giving them a default value:


def func(x, y, z=None):
print(z)

func(5, 6) # Output: None


func(5, 6, 7) # Output: 7

 If not passed, the optional parameter (z) defaults to None or


whatever value you specify

✅ Summary of Function Concepts

Concept Example Notes

Basic Definition def func(): Defines a function

With Parameters def func(x, y): Function expects 2 arguments

Calling func(5, 6) Executes the function


Concept Example Notes

Sends value(s) back to the


Returning Values return x * y
caller

Multiple Returns return a, b Returns a tuple

Unpacking Assigns tuple values to


r1, r2 = func()
Return variables

Default
def func(x, y, z=None): z is optional
Parameters

Nested Functions def outer(): def inner(): Inner defined inside outer

Function as Can be passed, returned, stored like Python treats functions as


Object data objects

🟪 *args and **kwargs in Python


These are advanced function parameters that allow your
function to accept a variable number of arguments, both
positional and keyword-based.

🔸 Why Are They Useful?

Sometimes you don't know how many arguments you will get when
calling a function - so Python allows flexibility with:

 *args → collects extra positional arguments (as a tuple)


 **kwargs → collects extra keyword arguments (as a dict)

✅ *args - Positional Arguments

 *args lets you pass any number of non-keyword


arguments to a function
 Internally, it collects them into a tuple
def func(*args):
print(args)

func(1, 2, 3, 4) # Output: (1, 2, 3, 4)

You can loop through them:


def func(*args):
for arg in args:
print(arg)

✅ **kwargs - Keyword Arguments

 **kwargs collects named arguments into a dictionary

💡 Syntax:
def func(**kwargs):
print(kwargs)

func(a=1, b=2) # Output: {'a': 1, 'b': 2}

You can loop through key-value pairs:


def func(**kwargs):
for key, value in kwargs.items():
print(f"{key} = {value}")

🔁 Combining *args and **kwargs

You can use both in a function, but *args must come


before **kwargs:
def func(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)

func(1, 2, three=3, four=4)


# Output:
# Args: (1, 2)
# Kwargs: {'three': 3, 'four': 4}

✅ Unpacking with * and ** (outside function)

Python allows you to unpack collections using:

 * → list/tuple unpacking
 ** → dictionary unpacking

🔹 Example with Lists:


def add(x, y):
print(x + y)

pair = [5, 10]


add(*pair) # Output: 15

🔹 Example with Dict:


def greet(name, age):
print(f"{name} is {age} years old")

info = {'name': 'Smriti', 'age': 21}


greet(**info) # Output: Smriti is 21 years old

Order doesn't matter with **kwargs if keys match parameter names.

✅ Advanced Example: Returning Functions

Functions are objects in Python. You can return one function


from another:
def outer(x):
def inner():
print(x)
return inner

f = outer(3)
f() # Output: 3

 This is called closure


 It shows how Python functions can be passed around like data

⚠️Gotcha: Using *args/**kwargs with print

Unpacking a list or dict directly into print():


args = [1, 2, 3]
kwargs = {'sep': '-', 'end': '\n'}
print(*args, **kwargs) # Output: 1-2-3
But if keys don't match expected keyword arguments, you'll get an
error:
kwargs = {'one': 1}
print(**kwargs) # ❌ Error: 'one' is not a valid keyword arg for print

🔒 Summary Table

Type
Feature Syntax Use Case
Returned

*args *args tuple Any number of positional args

**kwargs **kwargs dict Any number of keyword args

expanded When passing arguments from


Unpacking *list, **dict
values collections

Functions as function Return/Store/Call functions


return inner
Data object dynamically

🟪 Python Scope & global Keyword


🔸 What is Scope?

Scope defines where a variable can be accessed or modified in


your code.

Python uses LEGB Rule to resolve variable names:

Scop
Description
e

L Local - Inside the current function

E Enclosing - In enclosing functions (nested)

G Global - Defined at top-level of script/module

B Built-in - Reserved names in Python (like len, print)


✅ Example: Local vs Global Scope
x = "global value"

def func():
x = "local value"
print(x)

func() # Output: local value


print(x) # Output: global value

 Inside func(), x is local and shadows the global x


 Changes made inside do not affect the outer x

🔸 Can a Function Modify a Global Variable?

Not unless you explicitly use the global keyword:

🚫 Without global:
x = "Tim"

def func():
x = "Changed"

func()
print(x) # Output: Tim ✅ (not changed)

✅ With global:
x = "Tim"

def func():
global x
x = "Changed"

func()
print(x) # Output: Changed ✅

🧠 Why?

 global x tells Python: "Don't make a new local variable - use the
one outside."

⚠️Caution: Avoid global


 It breaks encapsulation
 Makes debugging harder
 Better alternatives:
o Use return values
o Use mutable objects (like lists/dictionaries) if needed

✅ Example with Returning Values (Best Practice)


x = "Tim"

def func(name):
return name

x = func("Changed")
print(x) # Output: Changed ✅

🔄 Extra: Accessing Global from Inside

Even without modifying, you can read a global variable from inside
a function:
x = 10

def func():
print(x)

func() # Output: 10 ✅

But trying to assign to it without global will make a new


local variable, which can confuse your program:
x = 10

def func():
x = x + 1 # ❌ Error: local variable 'x' referenced before assignment

func()

🧠 Summary Table

Keyword Use Case Scope Affected

None Local variable (default) Local to function


Keyword Use Case Scope Affected

global Modify a global variable Global scope

Best
Use return instead Clean code practice
Practice

🟥 Python Exceptions & Exception Handling


🔸 What is an Exception?

An exception is an error that occurs during the execution of a


program, which interrupts the normal flow unless it is handled.

In Python, exceptions can be:

 Raised using the raise keyword


 Handled using try-except-finally blocks

🚫 Raising Exceptions Manually

✅ Syntax:
raise Exception("Something went wrong")

 raise is similar to throw in Java/C++


 You can raise built-in exceptions like FileExistsError, ValueError,
etc.
 You can also create custom exceptions when you get
into Object-Oriented Programming (OOP) by
subclassing Exception

▶️Example:
raise Exception("Bad") # This halts the program with Exception: Bad

 Once Python hits the raise statement, the


program immediately stops execution and throws the error

✅ Raising Specific Built-in Exceptions


raise FileExistsError("File already exists")
raise ValueError("Invalid input")

You can pass a message or description inside the parentheses

🔸 Handling Exceptions with try-except

In Python, the syntax for exception handling is:


try:
# Code that might raise an exception
except ExceptionType as e:
# Handle the exception, 'e' contains the error object
finally:
# Optional cleanup code that runs no matter what

▶️Basic Example:
try:
result = 7 / 0
except Exception as e:
print(e) # Output: division by zero

 The try block runs the risky code


 If an exception occurs, it's caught in the except block
 e stores the actual error object
 This prevents the program from crashing

🔹 General except (Catches Any Error):


try:
risky_operation()
except:
print("Something went wrong")

 No error type is specified → any exception is caught


 This is not recommended in real-world code as it hides the
actual error type

🔹 Specific Exception Catching

You can catch only specific errors:


try:
result = 7 / 0
except ZeroDivisionError as e:
print("Caught division error:", e)

Useful when you want to handle different errors differently

🔸 finally Block

 The finally block always executes - whether or not an


exception occurred
 Common use: cleanup tasks like closing files, database
connections, etc.

▶️Example:
python
Copy
Download
try:
result = 7 / 0
except Exception as e:
print("Caught:", e)
finally:
print("This will always run")

🧾 Output:
Caught: division by zero
This will always run

Summary Table:

Componen
Purpose Notes
t

raise Manually trigger an exception Like throw in other languages

try Wrap code that may fail Starts the protected block

except Catch the exception Can be general or specific

as e Access exception object e holds the error message

finally Run regardless of exception Good for cleanup


🔁 Example Recap
try:
x=7/0
except ZeroDivisionError as e:
print("Handled:", e)
finally:
print("Always runs")

🧾 Output:
Handled: division by zero
Always runs

🟦 F-Strings (Formatted Strings)


✅ What is an F-string?

 Introduced in Python 3.6+


 Allows for embedding expressions and variables directly
inside strings
 Very readable and efficient way to format strings

✅ Syntax:
f"some string {expression_or_variable}"

 Can use either lowercase f or uppercase F before the string


 Anything inside {} will be evaluated and turned into a string

▶️Examples:

1. Evaluating an Expression:
s = f"6 + 8 = {6 + 8}"
print(s) # Output: 6 + 8 = 14

2. Embedding Variables:
name = "Smriti"
score = 89
message = f"Hello {name}, your score is {score}"
print(message) # Output: Hello Smriti, your score is 89

🛠 Why use F-strings?

Cleaner alternative to:


"Hello " + name + ", your score is " + str(score)

 Avoids manual str() conversion and concatenation


 More readable and maintainable
 Faster execution than string concatenation

🔹 Advanced F-String Features

Formatting Numbers:
price = 49.99
print(f"Price: {price:.2f}") # Output: Price: 49.99

Calling Functions:
def get_name():
return "Alice"

print(f"Name: {get_name()}") # Output: Name: Alice

Multi-line F-strings:
name = "Bob"
age = 25
message = (
f"Name: {name}\n"
f"Age: {age}\n"
f"Next year: {age + 1}"
)
print(message)

Using Expressions:
items = 3
price = 9.99
print(f"Total: ${items * price:.2f}") # Output: Total: $29.97
⚠️Important Notes:

1. F-strings are evaluated at runtime


2. The expressions inside {} must be valid Python expressions
3. You can't use backslashes (\) directly inside the curly braces
4. F-strings are faster than % formatting and str.format()

🔹 Comparison with Other String Formatting Methods

1. % formatting (old style):


"Hello %s, your score is %d" % (name, score)
2. str.format() (new style):
"Hello {}, your score is {}".format(name, score)
3. f-strings (best for Python 3.6+):
f"Hello {name}, your score is {score}"

F-strings are generally preferred because:

 More readable
 Less verbose
 Faster execution
 Variables are visible in the same line where they're used

🧠 Summary Table:

Feature Example Notes

Basic f-string f"Hello {name}" Simple variable insertion

Can include any valid


Expressions f"Total: {price * quantity}"
expression

Formatting
f"Price: {price:.2f}" Supports all format specifiers
numbers

Function calls f"Name: {get_name()}" Can call functions inside

Multi-line f"Line1\nLine2" Works with multi-line strings

Compiled at runtime for


Performance Faster than other methods
efficiency
🟩 Lambda Functions in Python
✅ What is a Lambda?

 A lambda is a one-line anonymous function


 Unlike regular functions, it does not use the def keyword
 It's primarily used when you need a small function
temporarily, especially in higher-order functions
like map, filter, and sorted

✅ Syntax
lambda arguments: expression

▶️Examples:

1. Basic Lambda
x = lambda x: x + 5
print(x(2)) # Output: 7

2. Multiple Parameters
add = lambda x, y: x + y
print(add(2, 32)) # Output: 34

❗ Important Note:

 Although assigning a lambda to a variable is possible, it's not


the recommended way to use lambdas
 They're better used directly inside functions like map() or filter()
 If your function is complex enough to need a name, you should
use a regular def function instead

🔹 Why Use Lambda Functions?

1. Conciseness: Write simple functions in a single line


2. Anonymous: Don't need to name temporary functions
3. Functional Programming: Work seamlessly with map(), filter(),
and sorted()
4. Readability: When used properly, can make code more
readable for simple operations

🔹 Limitations of Lambda Functions

1. Can only contain a single expression


2. Cannot include statements like if, for, while, etc. (though
conditional expressions are allowed)
3. No annotations or type hints
4. Less readable for complex operations

▶️More Examples:

Conditional Expression
is_even = lambda x: True if x % 2 == 0 else False
print(is_even(4)) # Output: True

Sorting with Lambda


names = ['Alice', 'Bob', 'Charlie', 'Dave']
sorted_names = sorted(names, key=lambda x: len(x))
print(sorted_names) # Output: ['Bob', 'Dave', 'Alice', 'Charlie']

🟨 map() and filter() Functions


These are built-in higher-order functions in Python and are often
used in combination with lambdas.

✅ map(function, iterable)

Purpose:

 Applies a function to each element in the iterable


 Returns a map object (convert it using list() to see the output)

▶️Example:
x = [1, 2, 4, 5, 6, 7]
mapped = map(lambda i: i + 2, x)
print(list(mapped)) # Output: [3, 4, 6, 7, 8, 9]
🔁 More Variation:
mapped = map(lambda i: i * 2, x)
print(list(mapped)) # Output: [2, 4, 8, 10, 12, 14]

Using Regular Function with map():


def add_two(n):
return n + 2

numbers = [1, 2, 3]
result = map(add_two, numbers)
print(list(result)) # Output: [3, 4, 5]

✅ filter(function, iterable)

Purpose:

 Filters elements from iterable for which the function returns


True
 Returns a filter object

▶️Example using Lambda:


x = [1, 2, 4, 5, 6, 7]
filtered = filter(lambda i: i % 2 == 0, x)
print(list(filtered)) # Output: [2, 4, 6]

▶️Example using Regular Function:


def is_even(i):
return i % 2 == 0

filtered = filter(is_even, x)
print(list(filtered)) # Output: [2, 4, 6]

✅ This shows why lambda is handy - we don't need to define a


separate function if it's small or used only once.

🔄 Comparing map() and filter()


Function Purpose Return Value Example

Transforms each map object map(lambda x: x*2,


map()
element (iterator) [1,2,3]) → [2,4,6]

Filters elements by filter object filter(lambda x: x>2,


filter()
condition (iterator) [1,2,3]) → [3]

🔹 Practical Examples

1. Processing Strings
names = ['alice', 'bob', 'charlie']
capitalized = map(lambda x: x.capitalize(), names)
print(list(capitalized)) # Output: ['Alice', 'Bob', 'Charlie']

2. Filtering Negative Numbers


numbers = [5, -2, 10, -8, 3]
positive = filter(lambda x: x > 0, numbers)
print(list(positive)) # Output: [5, 10, 3]

3. Combining map and filter


numbers = [1, 2, 3, 4, 5]
result = map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers))
print(list(result)) # Output: [4, 16] (squares of even numbers)

🔹 Performance Considerations

1. Lazy Evaluation: Both map and filter return iterators, meaning


they don't compute values until needed
2. Memory Efficient: Process one item at a time rather than
creating intermediate lists
3. Often Faster than equivalent list comprehensions for large
datasets

🔹 Alternative: List Comprehensions

While map and filter are useful, Python also offers list
comprehensions that can often achieve the same result more
readably:
map() equivalent
# Using map
result = map(lambda x: x*2, numbers)

# Using list comprehension


result = [x*2 for x in numbers]

filter() equivalent
# Using filter
result = filter(lambda x: x > 0, numbers)

# Using list comprehension


result = [x for x in numbers if x > 0]

🧠 When to Use Which?

 Use map/filter with lambdas for simple operations


 Use list comprehensions for more complex transformations or
filtering
 Consider readability - sometimes list comprehensions are
clearer
 For very large datasets, map/filter might be more memory
efficient

🔚 Summary Table
Concept Syntax Example Best For

Lambda
lambda x: x + 1 Small, one-time use functions
Function

Applying same operation to


map() map(func, iterable)
all items

Selecting items that meet


filter() filter(func, iterable)
condition

Combined map(func1, filter(func2, iterable)) Processing filtered items

You might also like