Introduction to Python
History
Python was created by Guido van Rossum in the late 1980s and first released in 1991. It was designed to emphasize code readability and developer productivity, using significant indentation to structure code. Over time Python grew a strong community and a rich standard library.
Major milestones include Python 2 (widely used for many years) and the release of Python 3 in 2008, which introduced improvements and some backward-incompatible changes. The community gradually migrated to Python 3 as the primary version. Today, Python 3 is the standard, with Python 2 officially deprecated since January 1, 2020.
Key Milestones:
- 1991: Python 0.9.0 released with classes, exception handling, functions, and core datatypes
- 2000: Python 2.0 introduced list comprehensions and garbage collection
- 2008: Python 3.0 released with major improvements (print function, better Unicode support, cleaner syntax)
- 2020: Python 2 officially sunset; Python 3 is the only supported version
Why Choose Python?
Python has become one of the most popular programming languages worldwide for several compelling reasons:
- Readable and Clean Syntax: Python's syntax is designed to be intuitive and readable, often resembling plain English. This makes it easier to learn and maintain code.
- Beginner-Friendly: Python is often the first language taught in schools and bootcamps because of its gentle learning curve.
- Versatile and Powerful: From web development to AI/ML, Python can handle diverse tasks across multiple domains.
- Rich Ecosystem: Thousands of libraries and frameworks (NumPy, pandas, Django, Flask, TensorFlow) extend Python's capabilities.
- Strong Community: Active community support, extensive documentation, and countless tutorials make problem-solving easier.
- Cross-Platform: Python runs on Windows, macOS, Linux, and more.
- High Demand: Python developers are in high demand across industries, making it a valuable career skill.
Try It: Your First Python Program
Below is a space to experiment with basic Python syntax. Try creating variables, printing output, and performing simple calculations.
Key Features
Interpreted Language
Python code is executed line by line by the Python interpreter, making debugging easier and allowing for interactive programming in environments like IDLE or Jupyter notebooks.
Dynamically Typed
You don't need to declare variable types explicitly. Python infers types at runtime, making code more flexible but requiring careful testing.
Object-Oriented
Python supports object-oriented programming with classes and objects, enabling code reusability and modular design.
Extensive Standard Library
Python comes with a "batteries included" philosophy, providing modules for file I/O, regular expressions, web protocols, data serialization, and much more.
Multi-Paradigm
Python supports procedural, object-oriented, and functional programming paradigms, giving developers flexibility in how they structure their code.
Use Cases
Python is a versatile language used across many domains because of its simple syntax and large ecosystem of libraries and frameworks. Common use cases include:
Web Development
Frameworks like Django and Flask make it easy to build robust, scalable web applications quickly. Django provides a full-featured MVC framework, while Flask offers a lightweight, flexible approach.
Data Science and Analysis
Python dominates the data science field with libraries like NumPy, pandas, and Matplotlib. These tools enable data manipulation, statistical analysis, and visualization.
Machine Learning and AI
Libraries such as scikit-learn, TensorFlow, and PyTorch make Python the go-to language for machine learning, deep learning, and artificial intelligence research and applications.
Automation and Scripting
Python excels at automating repetitive tasks like file management, web scraping (with BeautifulSoup and Scrapy), and system administration.
Scientific Computing
Python is widely used in scientific research and engineering with tools like SciPy, SymPy, and Biopython for complex calculations and simulations.
Game Development
While not the primary choice for AAA games, Python is used for game development with libraries like Pygame for 2D games and prototyping.
Education
Python's simplicity makes it ideal for teaching programming fundamentals in schools, universities, and online courses.
DevOps and Cloud
Python is used for infrastructure automation, configuration management (Ansible), and cloud service interactions (AWS SDK, Google Cloud SDK).
Try It: Explore Python's Versatility
Experiment with different Python operations: string manipulation, list operations, or simple math calculations.
Getting Started
Installing Python
To start programming in Python, you need to install it on your computer:
- Visit the official Python website: python.org
- Download the latest version of Python 3
- Run the installer (make sure to check "Add Python to PATH" on Windows)
- Verify installation by opening a terminal/command prompt and typing:
python --version
Your First Program
The traditional first program in any language is "Hello, World!". In Python, it's remarkably simple:
print("Hello, World!")
That's it! Just one line creates output. This simplicity is what makes Python so appealing to beginners.
Development Environments
You can write Python code in various environments:
- IDLE: Comes bundled with Python, simple and lightweight
- VS Code: Popular, feature-rich editor with excellent Python support
- PyCharm: Professional IDE specifically designed for Python
- Jupyter Notebook: Interactive environment perfect for data science and learning
- Sublime Text / Atom: Lightweight text editors with Python plugins
Try It: Create Your Own Hello World
Practice writing your first Python program. Try variations of Hello World with different messages.
What's Next?
Now that you understand what Python is and why it's valuable, you're ready to dive into the fundamentals:
- Syntax and Output: Learn how Python code is structured and how to display information
- Datatypes and Variables: Understand how to store and manage data
- Control Flow: Make decisions and repeat actions in your programs
- Functions: Organize code into reusable blocks
- Data Structures: Work with collections of data efficiently
Use the sidebar to navigate to the next topic and continue your Python learning journey!
Syntax and Output
Overview
Python code is written using a clean, easy-to-read syntax that emphasizes readability and simplicity.
Unlike many other programming languages, Python uses indentation (whitespace) to
define code blocks instead of braces or keywords. Output is typically produced with the built-in
print() function.
This design philosophy makes Python code look almost like pseudocode, which reduces the learning curve and makes programs easier to understand and maintain.
Basic Syntax Rules
1. Statements and Line Endings
In Python, each statement typically appears on its own line. Unlike languages like C or Java, you don't need to end statements with a semicolon (though you can use semicolons to separate multiple statements on one line).
name = "Alice" # This is a complete statementage = 25 # Each variable assignment is on its own line
2. Line Continuation
Long statements can be split across multiple lines using a backslash (\) or by placing
expressions inside parentheses, brackets, or braces.
total = 1 + 2 + 3 + \ 4 + 5 + 6# Or using parentheses:total = (1 + 2 + 3 + 4 + 5 + 6)
3. Case Sensitivity
Python is case-sensitive, meaning Variable, variable, and
VARIABLE are three different identifiers.
Try It: Practice Basic Syntax
Write simple Python statements and see how line endings work. Try creating variables and printing them.
Indentation
Indentation is critical in Python – it's not just for readability, it's part of the syntax. Indentation defines code blocks and scope.
Why Indentation Matters
- Indentation replaces braces
{ }used in other languages - All statements within a block must be indented by the same amount
- The standard is 4 spaces per indentation level (not tabs)
- Inconsistent indentation will cause an
IndentationError
Example:
if True: print("This is indented") # 4 spaces print("Still in the block") # Same indentationprint("Back to no indentation") # Outside the block
Important: Never mix tabs and spaces for indentation. Most modern code editors automatically convert tabs to spaces.
Try It: Practice Indentation
Experiment with indentation by creating if statements or other block structures. See what happens with incorrect indentation.
The Print Function
The print() function is your primary tool for displaying output in Python. It sends text
or data to the console/terminal.
Basic Usage
print("Hello, World!")print(42)print(3.14159)
Printing Multiple Items
You can print multiple items separated by commas. Python automatically adds a space between them.
print("Age:", 25)# Output: Age: 25
Customizing Separators
Use the sep parameter to change how items are separated:
print("apple", "banana", "cherry", sep=", ")# Output: apple, banana, cherry
Controlling Line Endings
By default, print() adds a newline at the end. Use the end parameter to
change this:
print("Hello", end=" ")print("World")# Output: Hello World
String Formatting in Print
Modern Python offers several ways to format strings for output:
1. f-strings (Python 3.6+) - Recommended
name = "Alice"age = 30print(f"My name is {name} and I am {age} years old")
2. .format() Method
print("My name is {} and I am {} years old".format(name, age))
3. % Operator (Older Style)
print("My name is %s and I am %d years old" % (name, age))
Try It: Master the Print Function
Practice using print() with different parameters. Try sep, end, and various formatting methods.
Receiving Input
The input() function allows your program to receive text input from the user. It
displays a prompt and waits for the user to type something and press Enter.
Basic Usage
name = input("Enter your name: ")print(f"Hello, {name}!")
Important: input() always returns a string. If you
need a number, you must convert it:
age = int(input("Enter your age: ")) # Convert to integerheight = float(input("Enter height: ")) # Convert to float
Try It: Combine Input and Output
Create a program that asks for user input and displays formatted output. Try different data types and formatting.
Common Syntax Errors to Avoid
- IndentationError: Mixing tabs and spaces, or inconsistent indentation levels
- SyntaxError: Missing colons after if, for, while, def, or class statements
- NameError: Using variables before defining them or misspelling variable names
- TypeError: Trying to concatenate strings with numbers without conversion
Always read error messages carefully – Python error messages are usually helpful in identifying what went wrong and where.
Quick Reference
- Statements end with a newline (no semicolons needed)
- Use 4 spaces for each indentation level
- Comments start with
# print()displays outputinput()receives user input (always returns a string)- Python is case-sensitive
- Indentation defines code blocks
Next Steps
Now that you understand Python's syntax and how to produce output, you're ready to learn about datatypes and variables – the building blocks for storing and manipulating data in your programs.
Datatypes & Variables
Overview
Python provides several built-in datatypes for storing different kinds of information: numbers, text, collections, and more. Variables are containers that store these values, and Python is dynamically typed, meaning you don't need to declare a variable's type explicitly – Python infers it automatically.
Understanding datatypes is fundamental to programming because different types of data support different operations and behave differently in your programs.
Variables
What is a Variable?
A variable is a named location in memory that stores a value. Think of it as a labeled box where you can put data and retrieve it later by using the label (variable name).
Creating Variables
In Python, you create a variable simply by assigning a value to it using the equals sign
=:
name = "Alice" # String variableage = 25 # Integer variableheight = 5.6 # Float variableis_student = True # Boolean variable
Variable Naming Rules
Follow these rules when naming variables:
- Must start with a letter (a-z, A-Z) or underscore (_)
- Can contain letters, numbers, and underscores
- Cannot start with a number
- Cannot use Python keywords (like
if,for,while, etc.) - Case-sensitive:
ageandAgeare different variables
Naming Conventions (Best Practices)
- Use snake_case for variable names:
user_name,total_amount - Use descriptive names:
student_countinstead ofsc - Constants should be in UPPERCASE:
MAX_SIZE = 100 - Avoid single-letter names except for counters (
i,j) or mathematical formulas
Multiple Assignment
Python allows you to assign multiple variables in one line:
x, y, z = 10, 20, 30a = b = c = 0 # All assigned the same value
Try It: Create and Use Variables
Practice creating variables with different names and values. Try multiple assignment and see how variables work.
Numeric Datatypes
1. Integer (int)
Whole numbers without a decimal point. Can be positive, negative, or zero.
count = 42temperature = -15zero = 0
Note: Python integers have unlimited precision – they can be as large as your memory allows!
2. Float (float)
Numbers with decimal points. Used for measurements, calculations requiring precision, etc.
pi = 3.14159price = 19.99negative_float = -7.5
Scientific Notation: You can use e for powers of 10:
large_number = 1.5e6 # 1,500,000small_number = 2.5e-3 # 0.0025
3. Complex (complex)
Numbers with real and imaginary parts, using j to denote the imaginary component.
z = 3 + 4jprint(z.real) # 3.0print(z.imag) # 4.0
Checking Type
Use the type() function to check a variable's datatype:
x = 10print(type(x)) #
Try It: Work with Numbers
Create variables of different numeric types. Use type() to check their types and perform basic arithmetic.
String (str)
Strings represent text data. They can be enclosed in single quotes, double quotes, or triple quotes for multi-line strings.
Creating Strings
name = "Alice" # Double quotesgreeting = 'Hello' # Single quotesmessage = """This isa multi-linestring""" # Triple quotes
String Operations
- Concatenation:
"Hello" + " " + "World"→"Hello World" - Repetition:
"Ha" * 3→"HaHaHa" - Length:
len("Python")→6 - Indexing:
"Python"[0]→"P"
Strings are immutable – once created, they cannot be changed. Any operation that appears to modify a string actually creates a new string.
Boolean (bool)
Booleans represent truth values: True or False. They're essential for
conditional logic and decision-making in programs.
is_active = Truehas_permission = False# From comparisons:result = (5 > 3) # Trueequal = (10 == 20) # False
Truthy and Falsy Values
In Python, certain values are considered "falsy" (evaluate to False in boolean context):
NoneFalse- Zero:
0,0.0 - Empty sequences:
"",[],(),{}
All other values are "truthy" (evaluate to True).
Collection Datatypes
1. List (list)
Ordered, mutable collection of items. Items can be of different types.
fruits = ["apple", "banana", "cherry"]mixed = [1, "text", 3.14, True]empty_list = []
Lists are versatile and the most commonly used collection type in Python.
2. Tuple (tuple)
Ordered, immutable collection. Once created, cannot be modified.
coordinates = (10, 20)rgb_color = (255, 128, 0)single_item = (42,) # Note the comma
Use tuples for data that shouldn't change, like coordinates or configuration values.
3. Dictionary (dict)
Unordered collection of key-value pairs. Keys must be unique and immutable.
person = { "name": "Alice", "age": 30, "city": "Seattle"}print(person["name"]) # Access by key
4. Set (set)
Unordered collection of unique items. Automatically removes duplicates.
unique_numbers = {1, 2, 3, 4, 5}letters = {'a', 'b', 'c'}# Duplicates are removed:numbers = {1, 2, 2, 3, 3, 3} # Result: {1, 2, 3}
Try It: Explore Collections
Create lists, tuples, dictionaries, and sets. Access their elements and see how they behave differently.
None Type
None is Python's null value. It represents the absence of a value or a null reference.
result = Noneif result is None: print("No value assigned")
Use is None or is not None to check for None values, not
== None.
Quick Type Conversion
You can convert between types using built-in functions:
# To integer:int("42") # "42" → 42int(3.14) # 3.14 → 3 (truncates)# To float:float("3.14") # "3.14" → 3.14float(42) # 42 → 42.0# To string:str(42) # 42 → "42"str(3.14) # 3.14 → "3.14"# To boolean:bool(0) # 0 → Falsebool(42) # 42 → True
See the Typecasting section for more detailed information on type conversion.
Try It: Convert Between Types
Practice converting values between different datatypes. Use type() to verify the conversions.
Quick Reference
- int — Integers (whole numbers):
42,-3 - float — Floating point numbers:
3.14,-0.5 - str — Strings (text):
"Hello",'Python' - bool — Booleans:
True,False - list — Ordered, mutable:
[1, 2, 3] - tuple — Ordered, immutable:
(1, 2, 3) - dict — Key-value pairs:
{"key": "value"} - set — Unique items:
{1, 2, 3} - NoneType — Null value:
None
Next Steps
Now that you understand Python's datatypes and how to store data in variables, you're ready to learn about typecasting – explicitly converting data from one type to another for more control in your programs.
Typecasting
Overview
Typecasting (also called type conversion) is the process of changing a value from one datatype to
another. Python performs some conversions automatically (implicit conversion), but
often you'll need to convert explicitly (explicit conversion) using built-in
functions like int(), float(), str(), and
list().
Understanding typecasting is crucial because different operations require specific datatypes, and user input always comes as strings and often needs conversion.
Implicit vs Explicit Conversion
Implicit Conversion (Automatic)
Python automatically converts smaller datatypes to larger ones to prevent data loss. This happens without your intervention.
x = 10 # inty = 3.5 # floatresult = x + y # Python converts x to float: 13.5print(type(result)) #
In this example, Python automatically converts the integer to a float before adding because float is a "wider" type that can represent both integers and decimals.
Explicit Conversion (Manual)
You explicitly convert values using conversion functions. This gives you full control over how data is converted.
text = "42"number = int(text) # Explicitly convert string to intprint(number + 8) # Now we can do math: 50
Try It: Explore Implicit and Explicit Conversion
Experiment with automatic and manual type conversions. See what happens when you mix different types.
Common Conversion Functions
1. Converting to Integer: int()
Converts a value to an integer (whole number). Truncates decimal portions.
# From float (truncates):int(3.99) # → 3 (not rounded!)int(-2.7) # → -2# From string:int("42") # → 42int(" 100 ") # → 100 (ignores whitespace)# From boolean:int(True) # → 1int(False) # → 0
Important: int("3.14") will cause an error! You must convert to float
first: int(float("3.14"))
2. Converting to Float: float()
Converts a value to a floating-point number (with decimal).
# From integer:float(42) # → 42.0# From string:float("3.14") # → 3.14float("100") # → 100.0# From boolean:float(True) # → 1.0float(False) # → 0.0
3. Converting to String: str()
Converts any value to a string representation. This almost always works!
str(42) # → "42"str(3.14) # → "3.14"str(True) # → "True"str([1, 2, 3]) # → "[1, 2, 3]"str(None) # → "None"
Use Case: Combining numbers with text in print statements:
age = 25message = "I am " + str(age) + " years old"# Or use f-strings (better): f"I am {age} years old"
4. Converting to Boolean: bool()
Converts any value to a boolean (True or False).
# Falsy values → False:bool(0) # → Falsebool("") # → False (empty string)bool([]) # → False (empty list)bool(None) # → False# Everything else → True:bool(42) # → Truebool("Hello") # → Truebool([1, 2, 3]) # → True
5. Converting to List, Tuple, Set
Convert between collection types:
# String to list:list("abc") # → ['a', 'b', 'c']# Tuple to list:list((1, 2, 3)) # → [1, 2, 3]# List to tuple:tuple([1, 2, 3]) # → (1, 2, 3)# List to set (removes duplicates):set([1, 2, 2, 3]) # → {1, 2, 3}
Try It: Practice Conversion Functions
Use int(), float(), str(), bool(), and collection conversion functions. Try edge cases!
Handling Conversion Errors
Common Errors
Not all conversions are possible. Here are common scenarios that cause errors:
- ValueError: Trying to convert invalid string to number
- TypeError: Incompatible types in operation
Examples of Invalid Conversions:
# ValueError - invalid literal:int("hello") # ERROR: can't convert text to intfloat("12.5.3") # ERROR: invalid format# TypeError - incompatible operation:"age: " + 25 # ERROR: can't concatenate str and int# Fix: "age: " + str(25)
Safe Conversion with Try-Except
Use try-except blocks to handle potential conversion errors gracefully:
user_input = "abc"try: number = int(user_input) print(f"Converted: {number}")except ValueError: print("Invalid number format!")
Validation Before Conversion
Check if conversion is possible using string methods:
text = "123"if text.isdigit(): number = int(text) print("Valid integer:", number)else: print("Not a valid integer")
Try It: Handle Conversion Errors
Experiment with invalid conversions and use try-except to handle them safely.
Practical Examples
Example 1: User Input Processing
Convert string input to numbers for calculations:
# All input() returns strings!age_str = input("Enter your age: ")age = int(age_str) # Convert to intyears_to_100 = 100 - ageprint(f"You have {years_to_100} years until 100!")
Example 2: Data Cleaning
Remove duplicates by converting list to set and back:
numbers = [1, 2, 2, 3, 4, 4, 5]unique = list(set(numbers)) # [1, 2, 3, 4, 5]
Example 3: Temperature Conversion
Convert between Celsius and Fahrenheit:
celsius_str = "25"celsius = float(celsius_str)fahrenheit = (celsius * 9/5) + 32print(f"{celsius}°C = {fahrenheit}°F")
Example 4: String to List for Processing
Convert comma-separated string to list:
fruits_str = "apple,banana,cherry"fruits_list = fruits_str.split(",") # ['apple', 'banana', 'cherry']
Try It: Real-World Typecasting
Create programs that use typecasting for practical tasks like input processing or data conversion.
Quick Reference
int(x)→ Convert to integer (truncates decimals)float(x)→ Convert to floating-point numberstr(x)→ Convert to stringbool(x)→ Convert to boolean (True/False)list(x)→ Convert to listtuple(x)→ Convert to tupleset(x)→ Convert to set (removes duplicates)
- All
input()values are strings – convert before doing math! - Use f-strings instead of converting numbers to strings for printing
- Use try-except for safe conversion of untrusted data
int("3.14")causes an error – useint(float("3.14"))instead
Next Steps
Now that you understand typecasting, you're ready to learn about operators – the symbols and operations used to manipulate and compare data in Python.
Operators
Overview
Operators are special symbols that perform operations on values and variables. Python provides a rich set of operators for arithmetic, comparison, logical operations, and more. Understanding operators is essential for writing expressions and making decisions in your programs.
Arithmetic Operators
Perform mathematical calculations on numbers.
| Operator | Name | Example | Result |
|---|---|---|---|
+ |
Addition | 5 + 3 |
8 |
- |
Subtraction | 5 - 3 |
2 |
* |
Multiplication | 5 * 3 |
15 |
/ |
Division | 5 / 2 |
2.5 |
// |
Floor Division | 5 // 2 |
2 (rounds down) |
% |
Modulus (Remainder) | 5 % 2 |
1 |
** |
Exponentiation | 5 ** 2 |
25 (5²) |
Special Notes:
- Division always returns a float: Even
6 / 3gives2.0 - Floor division rounds down:
-7 // 2gives-4, not-3 - Modulus useful for: Checking even/odd numbers, cycling values
Try It: Practice Arithmetic Operators
Experiment with different arithmetic operations. Try edge cases like division by zero or large exponents.
Comparison (Relational) Operators
Compare two values and return a boolean (True or False).
| Operator | Name | Example | Result |
|---|---|---|---|
== |
Equal to | 5 == 5 |
True |
!= |
Not equal to | 5 != 3 |
True |
> |
Greater than | 5 > 3 |
True |
< |
Less than | 5 < 3 |
False |
>= |
Greater than or equal | 5 >= 5 |
True |
<= |
Less than or equal | 5 <= 3 |
False |
Important: Use == for comparison, not = (which is
assignment)!
Try It: Practice Comparison Operators
Compare different values and types. See how Python compares strings, numbers, and booleans.
Logical Operators
Combine multiple boolean expressions or invert truth values.
and
Returns True if both conditions are true.
(5 > 3) and (10 > 5) # True (both are true)(5 > 3) and (10 < 5) # False (one is false)
or
Returns True if at least one condition is true.
(5 > 3) or (10 < 5) # True (one is true)(5 < 3) or (10 < 5) # False (both are false)
not
Inverts the boolean value (True becomes False, False becomes True).
not (5 > 3) # False (inverts True)not (5 < 3) # True (inverts False)
Truth Table:
| A | B | A and B | A or B | not A |
|---|---|---|---|---|
| True | True | True | True | False |
| True | False | False | True | False |
| False | True | False | True | True |
| False | False | False | False | True |
Assignment Operators
Assign values to variables, often with simultaneous operations.
| Operator | Example | Equivalent To |
|---|---|---|
= |
x = 5 |
Basic assignment |
+= |
x += 3 |
x = x + 3 |
-= |
x -= 3 |
x = x - 3 |
*= |
x *= 3 |
x = x * 3 |
/= |
x /= 3 |
x = x / 3 |
//= |
x //= 3 |
x = x // 3 |
%= |
x %= 3 |
x = x % 3 |
**= |
x **= 3 |
x = x ** 3 |
Try It: Logical and Assignment Operators
Practice combining conditions with logical operators and use compound assignment operators.
Identity Operators
Check if two variables refer to the same object in memory.
is
Returns True if both variables point to the same object.
a = [1, 2, 3]b = ac = [1, 2, 3]print(a is b) # True (same object)print(a is c) # False (different objects, same content)
is not
Returns True if variables point to different objects.
print(a is not c) # True (different objects)
Note: Use is for checking None: if x is None:
Membership Operators
Test if a value exists in a sequence (string, list, tuple, etc.).
in
Returns True if value is found in the sequence.
"a" in "apple" # True3 in [1, 2, 3, 4] # True"key" in {"key": 42} # True (checks dict keys)
not in
Returns True if value is NOT found in the sequence.
"x" not in "apple" # True5 not in [1, 2, 3] # True
Bitwise Operators
Perform operations on binary representations of integers.
| Operator | Name | Example |
|---|---|---|
& |
AND | 5 & 3 → 1 |
| |
OR | 5 | 3 → 7 |
^ |
XOR | 5 ^ 3 → 6 |
~ |
NOT | ~5 → -6 |
<< |
Left Shift | 5 << 1 → 10 |
>> |
Right Shift | 5 >> 1 → 2 |
Note: Bitwise operators are less common in everyday programming but useful for low-level operations and optimizations.
Try It: Advanced Operators
Experiment with identity, membership, and bitwise operators. See how they work in different contexts.
Operator Precedence
When multiple operators appear in an expression, Python follows a specific order (precedence):
- Parentheses:
()— Highest priority - Exponentiation:
** - Unary:
+x,-x,~x - Multiplication/Division:
*,/,//,% - Addition/Subtraction:
+,- - Bitwise shifts:
<<,>> - Bitwise AND:
& - Bitwise XOR:
^ - Bitwise OR:
| - Comparison:
==,!=,>,<,>=,<=,is,in - Logical NOT:
not - Logical AND:
and - Logical OR:
or— Lowest priority
Example:
result = 5 + 3 * 2 # Multiplication first: 5 + 6 = 11result = (5 + 3) * 2 # Parentheses first: 8 * 2 = 16
Best Practice: Use parentheses to make your intentions explicit, even when not strictly necessary!
Try It: Test Operator Precedence
Write complex expressions and verify the order of operations. Use parentheses to change the order.
Next Steps
Now that you understand operators, you're ready to learn about conditional statements – using operators to make decisions and control the flow of your programs with if, elif, and else.
Conditional Statements
Overview
Conditional statements allow your program to make decisions and execute different code blocks based
on whether certain conditions are true or false. Python uses if, elif, and
else keywords to control program flow. Conditions are boolean expressions – combine
them with logical operators like and, or, and not.
The if Statement
The if statement executes a block of code only if a condition is true.
Basic Syntax:
if condition: # code executes if condition is True statement1 statement2
Example:
age = 18if age >= 18: print("You are an adult") print("You can vote")
Important: The colon (:) is required after the condition, and the code
block must be indented!
Try It: Practice if Statements
Write if statements with different conditions. Test with both true and false conditions.
The if-else Statement
The else statement provides an alternative block of code that executes when the if
condition is false.
Syntax:
if condition: # executes if Trueelse: # executes if False
Example:
temperature = 25if temperature > 30: print("It's hot outside")else: print("The weather is pleasant")
The elif Statement
elif (short for "else if") allows you to check multiple conditions in sequence. Python
checks each condition from top to bottom and executes the first matching block.
Syntax:
if condition1: # executes if condition1 is Trueelif condition2: # executes if condition1 is False and condition2 is Trueelif condition3: # executes if above are False and condition3 is Trueelse: # executes if all conditions are False
Example:
score = 85if score >= 90: grade = "A"elif score >= 80: grade = "B"elif score >= 70: grade = "C"elif score >= 60: grade = "D"else: grade = "F"print(f"Your grade is: {grade}") # Output: Your grade is: B
Note: Once a condition is true, Python executes that block and skips the rest.
Try It: Practice if-elif-else Chains
Create grade calculators or decision trees using multiple elif statements.
Nested Conditional Statements
You can place if statements inside other if statements to create complex decision logic.
Example:
age = 20has_license = Trueif age >= 18: if has_license: print("You can drive") else: print("You need a license")else: print("You're too young to drive")
Better Alternative: Often you can use logical operators instead of nesting:
if age >= 18 and has_license: print("You can drive")elif age >= 18: print("You need a license")else: print("You're too young to drive")
Combining Multiple Conditions
Using and
All conditions must be true:
temperature = 25is_sunny = Trueif temperature > 20 and is_sunny: print("Perfect day for a picnic!")
Using or
At least one condition must be true:
day = "Saturday"if day == "Saturday" or day == "Sunday": print("It's the weekend!")
Using not
Inverts the condition:
is_raining = Falseif not is_raining: print("Let's go outside!")
Complex Combinations:
age = 25income = 50000has_debt = Falseif (age >= 18 and income > 30000) and not has_debt: print("Loan approved")
Try It: Complex Conditional Logic
Combine multiple conditions using and, or, and not. Create realistic scenarios with nested logic.
Ternary (Conditional) Operator
Python provides a shorthand for simple if-else statements in a single line.
Syntax:
value_if_true if condition else value_if_false
Example:
# Traditional if-else:age = 20if age >= 18: status = "adult"else: status = "minor"# Ternary operator (one line):status = "adult" if age >= 18 else "minor"
More Examples:
# Find maximum:max_value = a if a > b else b# Even or odd:result = "even" if num % 2 == 0 else "odd"# In print statements:print("Pass" if score >= 50 else "Fail")
Best Practice: Use ternary operators for simple conditions. For complex logic, stick with traditional if-else for readability.
Try It: Practice Ternary Operators
Rewrite traditional if-else statements as ternary expressions. Keep them simple and readable.
Common Conditional Patterns
Pattern 1: Checking Ranges
if 0 <= score <= 100: print("Valid score")else: print("Invalid score")
Pattern 2: Checking Multiple Values
if choice in [1, 2, 3]: print("Valid option")if color in ["red", "blue", "green"]: print("Primary color")
Pattern 3: Checking None
if value is None: print("No value assigned")if value is not None: print(f"Value is: {value}")
Pattern 4: Checking Empty Collections
my_list = []if my_list: # Truthy check print("List has items")else: print("List is empty")
Best Practices
- Use meaningful conditions:
if is_validis clearer thanif x == True - Avoid unnecessary else: If you return in the if block, else is redundant
- Order matters in elif: Put most specific conditions first
- Use parentheses for clarity: In complex conditions, use () to show intent
- Keep it simple: If nested logic gets too deep, consider breaking into functions
- Test edge cases: Always check boundary values (0, empty strings, None)
Next Steps
Now that you understand conditional statements, you're ready to learn about loops – repeating blocks of code multiple times using for and while loops.
Loops
Overview
Loops allow you to repeat a block of code multiple times without writing it repeatedly. Python
provides two main types of loops: for loops (for iterating over sequences) and
while loops (for repeating until a condition becomes false). Mastering loops is
essential for processing collections, automating repetitive tasks, and creating efficient programs.
for Loops
The for loop iterates over a sequence (list, tuple, string, range, etc.) and executes
code for each item.
Basic Syntax:
for variable in sequence: # code to execute for each item statement(s)
Example: Iterating Over a List
fruits = ["apple", "banana", "cherry"]for fruit in fruits: print(fruit)# Output:# apple# banana# cherry
Example: Iterating Over a String
for letter in "Python": print(letter)# Output: P y t h o n (each on new line)
Example: Iterating Over a Dictionary
person = {"name": "Alice", "age": 30, "city": "Seattle"}# Iterate over keys:for key in person: print(key, "=", person[key])# Iterate over key-value pairs:for key, value in person.items(): print(f"{key}: {value}")
Try It: Practice for Loops
Create for loops that iterate over different sequences: lists, strings, dictionaries, and tuples.
The range() Function
The range() function generates a sequence of numbers, perfect for when you need to
repeat something a specific number of times.
Three Forms of range():
1. range(stop)
Generates numbers from 0 to stop-1:
for i in range(5): print(i) # Output: 0 1 2 3 4
2. range(start, stop)
Generates numbers from start to stop-1:
for i in range(2, 6): print(i) # Output: 2 3 4 5
3. range(start, stop, step)
Generates numbers from start to stop-1, incrementing by step:
for i in range(0, 10, 2): print(i) # Output: 0 2 4 6 8# Counting backwards:for i in range(10, 0, -1): print(i) # Output: 10 9 8 7 6 5 4 3 2 1
Practical Examples:
# Print multiplication table:for i in range(1, 11): print(f"5 x {i} = {5 * i}")# Access list with indices:fruits = ["apple", "banana", "cherry"]for i in range(len(fruits)): print(f"Index {i}: {fruits[i]}")
Try It: Master range()
Use range() with different parameters. Create counting patterns, multiplication tables, or indexed loops.
while Loops
A while loop repeats as long as a condition remains true. Unlike for loops, while loops
are used when you don't know in advance how many iterations are needed.
Basic Syntax:
while condition: # code to execute # update condition to eventually become False
Example: Simple Counter
count = 0while count < 5: print(count) count += 1 # Important: update the counter!# Output: 0 1 2 3 4
Example: User Input Validation
password = ""while password != "secret": password = input("Enter password: ")print("Access granted!")
Example: Sum Until Condition
total = 0num = 1while total < 100: total += num num += 1print(f"Sum reached {total} after {num-1} iterations")
Warning: Make sure the condition eventually becomes False, or you'll create an infinite loop!
Try It: Practice while Loops
Create while loops with different conditions. Try countdown timers, sum calculations, or validation loops.
Loop Control: break and continue
break Statement
Immediately exits the loop, regardless of the condition:
for i in range(10): if i == 5: break # Exit loop when i is 5 print(i)# Output: 0 1 2 3 4 (stops at 5)
continue Statement
Skips the rest of the current iteration and moves to the next:
for i in range(10): if i % 2 == 0: continue # Skip even numbers print(i)# Output: 1 3 5 7 9 (only odd numbers)
Practical Example: Finding First Match
numbers = [3, 7, 2, 9, 15, 4]target = 9for i, num in enumerate(numbers): if num == target: print(f"Found {target} at index {i}") break
else Clause with Loops
Python's loops can have an else clause that executes when the loop completes normally
(not interrupted by break).
with for Loop:
for i in range(5): print(i)else: print("Loop completed successfully")
Practical Use: Search with Result
numbers = [1, 3, 5, 7, 9]search = 6for num in numbers: if num == search: print(f"Found {search}!") breakelse: print(f"{search} not found in the list")
Nested Loops
A loop inside another loop. Useful for working with multi-dimensional data or creating patterns.
Example: Multiplication Table
for i in range(1, 4): for j in range(1, 4): print(f"{i} x {j} = {i*j}") print() # Blank line after each row
Example: Pattern Printing
# Print a triangle:for i in range(1, 6): for j in range(i): print("*", end="") print() # New line# Output:# *# **# ***# ****# *****
Example: Iterating 2D List
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]for row in matrix: for item in row: print(item, end=" ") print() # New line after each row
Try It: Advanced Loop Patterns
Experiment with break, continue, else clauses, and nested loops. Create patterns or search algorithms.
Useful Loop Functions
enumerate()
Get both index and value when iterating:
fruits = ["apple", "banana", "cherry"]for index, fruit in enumerate(fruits): print(f"{index}: {fruit}")# Output:# 0: apple# 1: banana# 2: cherry
zip()
Iterate over multiple sequences simultaneously:
names = ["Alice", "Bob", "Charlie"]ages = [25, 30, 35]for name, age in zip(names, ages): print(f"{name} is {age} years old")
Loop Best Practices
- Choose the right loop: Use
forwhen you know iterations count;whilewhen condition-based - Avoid infinite loops: Always ensure while loop conditions can become False
- Use meaningful names:
for student in students:notfor x in y: - Minimize work inside loops: Move constant calculations outside the loop
- Use enumerate(): Instead of
range(len(list))when you need indices - Break long loops into functions: Improves readability and testing
- Be careful with nested loops: They can become slow with large datasets
Try It: Comprehensive Loop Practice
Combine different loop types and techniques. Create practical programs using enumerate(), zip(), and loop control.
Next Steps
Now that you understand loops, you're ready to learn about jumping statements (break, continue, pass, and return) in more detail to gain fine control over program flow.
Jumping Statements
Overview
Jumping statements alter the normal flow of program execution by transferring control to different
parts of the code. Python provides several jumping statements: break (exit loops),
continue (skip to next iteration), pass (do nothing placeholder), and
return (exit functions with a value). These statements give you precise control over
how your program executes.
break Statement
The break statement immediately terminates the innermost loop (for or while) and
transfers control to the statement immediately following the loop.
Basic Usage:
for i in range(10): if i == 5: break # Exit loop when i equals 5 print(i)# Output: 0 1 2 3 4
Example: Search and Exit
numbers = [1, 5, 3, 9, 7, 2]target = 9for index, num in enumerate(numbers): if num == target: print(f"Found {target} at index {index}") break print(f"Checking index {index}")
Example: Input Validation
while True: age = input("Enter your age (or 'quit' to exit): ") if age.lower() == 'quit': break if age.isdigit() and int(age) > 0: print(f"Age accepted: {age}") break print("Invalid input, try again")
break in Nested Loops:
The break statement only exits the innermost loop:
for i in range(3): for j in range(5): if j == 2: break # Only breaks inner loop print(f"i={i}, j={j}") print("Inner loop ended")
Try It: Practice break Statement
Use break to exit loops early. Create search functions or input validation loops.
continue Statement
The continue statement skips the rest of the current iteration and immediately moves to
the next iteration of the loop.
Basic Usage:
for i in range(10): if i % 2 == 0: continue # Skip even numbers print(i)# Output: 1 3 5 7 9 (only odd numbers)
Example: Filter Data
scores = [45, 92, 78, 55, 30, 88]for score in scores: if score < 50: continue # Skip failing scores print(f"Passing score: {score}")
Example: Skip Invalid Items
data = ["10", "abc", "20", "", "30", "xyz"]total = 0for item in data: if not item.isdigit(): continue # Skip non-numeric items total += int(item)print(f"Total: {total}") # Total: 60
break vs continue:
- break: Exits the loop completely
- continue: Skips current iteration, continues with next
Try It: Practice continue Statement
Use continue to skip certain iterations. Filter lists, skip invalid data, or process selective items.
pass Statement
The pass statement is a null operation – it does nothing. It's used as a placeholder
when a statement is required syntactically but no code needs to execute.
Why Use pass?
- Python requires at least one statement in code blocks
- Useful during development as a placeholder
- Helps create empty classes or functions temporarily
Example: Empty Function Placeholder
# Function definition for later implementation:def calculate_tax(amount): pass # TODO: Implement tax calculation
Example: Empty Class
# Class skeleton:class User: pass # Will add methods later# Can still create instances:user = User()
Example: Conditional Placeholder
score = 85if score > 90: print("Excellent!")elif score > 70: pass # Handle this condition laterelse: print("Needs improvement")
Example: Ignoring Exceptions
try: risky_operation()except ValueError: pass # Silently ignore ValueError
Note: While pass is useful during development, don't leave it in
production code without a comment explaining why it's empty!
Try It: Practice pass Statement
Create placeholder functions and classes using pass. Experiment with conditional blocks.
return Statement
The return statement immediately exits a function and optionally returns a value to the
caller. This is one of the most important jumping statements.
Basic Usage:
def add(a, b): return a + b # Exit function and return resultresult = add(5, 3)print(result) # Output: 8
Return Without Value:
def greet(name): if not name: return # Exit early if no name print(f"Hello, {name}!")greet("") # Does nothinggreet("Alice") # Output: Hello, Alice!
Multiple Return Statements:
def categorize_age(age): if age < 13: return "child" elif age < 20: return "teenager" elif age < 65: return "adult" else: return "senior"
Returning Multiple Values:
def get_stats(numbers): total = sum(numbers) count = len(numbers) average = total / count return total, count, average # Returns tuplet, c, avg = get_stats([10, 20, 30])print(f"Total: {t}, Count: {c}, Average: {avg}")
Note: If a function doesn't have a return statement, it implicitly returns
None.
Try It: Practice return Statement
Create functions with return statements. Try returning single values, multiple values, and early returns.
Practical Examples
Example 1: Prime Number Checker
def is_prime(n): if n < 2: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False # Found divisor, not prime return True
Example 2: Find First Negative Number
numbers = [5, 12, -3, 8, -1, 20]for num in numbers: if num < 0: print(f"First negative: {num}") break
Example 3: Process Valid Items Only
items = ["apple", "", "banana", None, "cherry", ""]for item in items: if not item: # Skip empty/None items continue print(f"Processing: {item}")
Best Practices
- Use break for early exit: When you've found what you need, exit the loop immediately
- Use continue for filtering: Skip invalid or unwanted items in a loop
- Use pass sparingly: It's fine during development, but add comments in production code
- Return early: In functions, handle edge cases with early returns for cleaner code
- Avoid deep nesting: Use return/continue to reduce nested if statements
- Be explicit: Even though functions return None implicitly, add
return Nonefor clarity - Document intention: Add comments when using pass or complex jumps
Quick Reference
- break — Exit loop completely
- continue — Skip current iteration, move to next
- pass — Do nothing (placeholder)
- return — Exit function, optionally return value
Next Steps
Now that you understand flow control with jumping statements, you're ready to learn about functions – organizing code into reusable blocks that can accept parameters and return values.
Functions
Overview
Functions are reusable blocks of code that perform specific tasks. They help organize complex programs into manageable pieces, avoid repetition (DRY principle - Don't Repeat Yourself), and make code easier to test and maintain. Functions can accept input through parameters, perform operations, and optionally return results.
Defining Functions
Use the def keyword to create a function.
Basic Syntax:
def function_name(parameters): """Docstring: Describes what the function does""" # Function body statement(s) return value # Optional
Simple Example:
def greet(): """Print a greeting message""" print("Hello, World!")# Call the function:greet() # Output: Hello, World!
Try It: Create Simple Functions
Define and call functions with no parameters. Practice writing docstrings.
Parameters and Arguments
Positional Parameters:
def greet(name): print(f"Hello, {name}!")greet("Alice") # Output: Hello, Alice!
Multiple Parameters:
def add(a, b): return a + bresult = add(5, 3)print(result) # Output: 8
Default Parameters:
Provide default values for parameters:
def greet(name, greeting="Hello"): print(f"{greeting}, {name}!")greet("Alice") # Output: Hello, Alice!greet("Bob", "Hi") # Output: Hi, Bob!greet("Charlie", greeting="Hey") # Output: Hey, Charlie!
Keyword Arguments:
Call functions using parameter names:
def describe_pet(animal, name): print(f"I have a {animal} named {name}.")# Positional:describe_pet("dog", "Buddy")# Keyword (order doesn't matter):describe_pet(name="Whiskers", animal="cat")
*args (Variable Positional Arguments):
Accept any number of positional arguments as a tuple:
def sum_all(*numbers): return sum(numbers)print(sum_all(1, 2, 3)) # Output: 6print(sum_all(10, 20, 30, 40)) # Output: 100
**kwargs (Variable Keyword Arguments):
Accept any number of keyword arguments as a dictionary:
def print_info(**info): for key, value in info.items(): print(f"{key}: {value}")print_info(name="Alice", age=30, city="Seattle")
Try It: Practice Function Parameters
Create functions with different parameter types. Try default values, *args, and **kwargs.
Return Values
Single Return Value:
def square(x): return x ** 2result = square(5)print(result) # Output: 25
Multiple Return Values:
Returns a tuple that can be unpacked:
def get_name_and_age(): return "Alice", 30name, age = get_name_and_age()print(f"{name} is {age} years old")
No Return (Returns None):
def print_message(msg): print(msg) # No return statement = returns Noneresult = print_message("Hello")print(result) # Output: None
Variable Scope
Local Scope:
Variables defined inside a function are local to that function:
def my_function(): local_var = 10 # Local variable print(local_var)my_function() # Output: 10# print(local_var) # ERROR: local_var not defined outside function
Global Scope:
Variables defined outside functions are global:
global_var = 20 # Global variabledef my_function(): print(global_var) # Can read global variablesmy_function() # Output: 20
Modifying Global Variables:
Use the global keyword to modify global variables inside functions:
counter = 0def increment(): global counter # Declare we're using global variable counter += 1increment()print(counter) # Output: 1
Best Practice: Avoid using global variables when possible. Pass data through parameters and return values instead.
Try It: Understand Variable Scope
Experiment with local and global variables. See what happens when you try to modify them.
Lambda Functions (Anonymous Functions)
Lambda functions are small, one-line functions defined without a name using the lambda
keyword.
Syntax:
lambda parameters: expression
Example: Basic Lambda:
# Regular function:def square(x): return x ** 2# Lambda equivalent:square = lambda x: x ** 2print(square(5)) # Output: 25
Example: Multiple Parameters:
add = lambda a, b: a + bprint(add(3, 5)) # Output: 8
Common Use: With Built-in Functions:
# Sort by second element in tuples:pairs = [(1, 'one'), (3, 'three'), (2, 'two')]sorted_pairs = sorted(pairs, key=lambda pair: pair[1])print(sorted_pairs) # [(1, 'one'), (3, 'three'), (2, 'two')]# Filter even numbers:numbers = [1, 2, 3, 4, 5, 6]evens = list(filter(lambda x: x % 2 == 0, numbers))print(evens) # [2, 4, 6]# Double each number:doubled = list(map(lambda x: x * 2, numbers))print(doubled) # [2, 4, 6, 8, 10, 12]
When to Use Lambda:
- Simple, one-line operations
- As arguments to functions like
map(),filter(),sorted() - When you need a quick throwaway function
When NOT to Use Lambda:
- Complex logic (use regular functions with descriptive names)
- When you need multiple statements
- When readability would suffer
Try It: Practice Lambda Functions
Create lambda functions and use them with map(), filter(), and sorted(). Compare with regular functions.
Docstrings and Documentation
Docstrings are string literals that appear right after function definitions to document what the function does.
Single-line Docstring:
def add(a, b): """Return the sum of two numbers.""" return a + b
Multi-line Docstring:
def calculate_area(length, width): """ Calculate the area of a rectangle. Parameters: length (float): The length of the rectangle width (float): The width of the rectangle Returns: float: The area of the rectangle """ return length * width
Accessing Docstrings:
print(add.__doc__)# Or use help():help(add)
Function Best Practices
- Single Responsibility: Each function should do one thing well
- Descriptive Names: Use verbs that describe what the function does:
calculate_total(),get_user_name() - Keep them short: If a function is too long, break it into smaller functions
- Document with docstrings: Explain what the function does, its parameters, and return value
- Avoid side effects: Functions should not modify global state unexpectedly
- Return values: Use return statements rather than printing (easier to test and reuse)
- Default arguments: Use them wisely, but never use mutable objects (lists, dicts) as defaults
- Type hints: Consider using type hints for clarity (Python 3.5+)
Try It: Create Complete Functions
Write well-documented functions with docstrings, proper parameter handling, and return values. Apply best practices!
Next Steps
Now that you understand functions, you're ready to explore lists – one of Python's most powerful and versatile data structures for storing collections of items.
Lists
Overview
Lists are one of Python's most versatile and commonly used data structures. A list is an ordered, mutable collection that can hold items of different types. Lists are perfect for storing sequences of data like numbers, names, objects, or even other lists. They support indexing, slicing, and a rich set of methods for manipulation.
Creating Lists
Basic Creation:
# Empty list:empty = []also_empty = list()# List with items:fruits = ["apple", "banana", "cherry"]numbers = [1, 2, 3, 4, 5]mixed = [1, "hello", 3.14, True] # Different types
From Other Sequences:
# From string:letters = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']# From range:numbers = list(range(5)) # [0, 1, 2, 3, 4]# From tuple:my_list = list((1, 2, 3)) # [1, 2, 3]
List with Repeated Elements:
zeros = [0] * 5 # [0, 0, 0, 0, 0]pattern = ["a", "b"] * 3 # ['a', 'b', 'a', 'b', 'a', 'b']
Try It: Create Different Lists
Practice creating lists in various ways. Try empty lists, mixed types, and conversion from other types.
Accessing List Elements
Indexing (Zero-Based):
fruits = ["apple", "banana", "cherry", "date"]# Positive indexing (from start):print(fruits[0]) # "apple" (first item)print(fruits[2]) # "cherry"# Negative indexing (from end):print(fruits[-1]) # "date" (last item)print(fruits[-2]) # "cherry" (second from end)
Slicing [start:stop:step]:
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]print(numbers[2:5]) # [2, 3, 4] (items 2-4)print(numbers[:4]) # [0, 1, 2, 3] (first 4)print(numbers[5:]) # [5, 6, 7, 8, 9] (from 5 onwards)print(numbers[::2]) # [0, 2, 4, 6, 8] (every 2nd item)print(numbers[::-1]) # [9, 8, 7... 0] (reversed)print(numbers[1:8:2]) # [1, 3, 5, 7] (1 to 7, step 2)
Try It: Index and Slice Lists
Practice accessing elements with positive/negative indices. Experiment with different slice patterns.
Modifying Lists
Changing Elements:
fruits = ["apple", "banana", "cherry"]fruits[1] = "blueberry" # Replace "banana"print(fruits) # ["apple", "blueberry", "cherry"]
Changing Multiple Elements:
numbers = [1, 2, 3, 4, 5]numbers[1:3] = [20, 30] # Replace items 1-2print(numbers) # [1, 20, 30, 4, 5]
Common List Methods
Adding Elements:
# append() - Add single item to end:fruits = ["apple", "banana"]fruits.append("cherry")print(fruits) # ["apple", "banana", "cherry"]# insert() - Add at specific position:fruits.insert(1, "blueberry") # Insert at index 1print(fruits) # ["apple", "blueberry", "banana", "cherry"]# extend() - Add multiple items:fruits.extend(["date", "elderberry"])print(fruits) # ["apple", "blueberry", "banana", "cherry", "date", "elderberry"]
Removing Elements:
# remove() - Remove first occurrence of value:fruits = ["apple", "banana", "cherry", "banana"]fruits.remove("banana") # Removes first "banana"print(fruits) # ["apple", "cherry" "banana"]# pop() - Remove and return item at index (default: last):last = fruits.pop() # Remove and return last itemsecond = fruits.pop(1) # Remove and return item at index 1# del - Delete by index or slice:del fruits[0] # Delete first itemdel fruits[1:3] # Delete items 1-2# clear() - Remove all items:fruits.clear() # Now fruits is []
Finding Elements:
fruits = ["apple", "banana", "cherry", "banana"]# index() - Find index of first occurrence:idx = fruits.index("banana") # 1# count() - Count occurrences:count = fruits.count("banana") # 2# in operator - Check membership:if "cherry" in fruits: print("Cherry is in the list")
Sorting and Reversing:
numbers = [3, 1, 4, 1, 5, 9, 2, 6]# sort() - Sort in place (modifies original):numbers.sort()print(numbers) # [1, 1, 2, 3, 4, 5, 6, 9]# sort(reverse=True) - Sort descending:numbers.sort(reverse=True)print(numbers) # [9, 6, 5, 4, 3, 2, 1, 1]# sorted() - Return new sorted list (doesn't modify original):original = [3, 1, 4]sorted_list = sorted(original)print(original) # [3, 1, 4]print(sorted_list) # [1, 3, 4]# reverse() - Reverse in place:numbers.reverse()
Copying Lists:
# Wrong way (creates reference, not copy):list1 = [1, 2, 3]list2 = list1 # Both point to same list!list2.append(4)print(list1) # [1, 2, 3, 4] - list1 changed too!# Right way (creates actual copy):list1 = [1, 2, 3]list2 = list1.copy() # Or list1[:]list2.append(4)print(list1) # [1, 2, 3] - unchangedprint(list2) # [1, 2, 3, 4]
Try It: Practice List Methods
Use methods to add, remove, find, and sort list elements. Experiment with append, extend, pop, sort, etc.
List Comprehensions
List comprehensions provide a concise way to create lists based on existing sequences.
Basic Syntax:
[expression for item in iterable]
Examples:
# Square each number:squares = [x**2 for x in range(10)]# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]# Convert to uppercase:fruits = ["apple", "banana", "cherry"]upper = [fruit.upper() for fruit in fruits]# ["APPLE", "BANANA", "CHERRY"]# Extract numbers from mixed list:mixed = [1, "hello", 3.14, True, 42]numbers = [x for x in mixed if isinstance(x, (int, float))]
With Conditions:
# Filter even numbers and double them:evens_doubled = [x*2 for x in range(10) if x % 2 == 0]# [0, 4, 8, 12, 16]# If-else in comprehension:labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]# ["even", "odd", "even", "odd", "even"]
Nested Comprehensions:
# Flatten 2D list:matrix = [[1, 2], [3, 4], [5, 6]]flat = [num for row in matrix for num in row]# [1, 2, 3, 4, 5, 6]
Try It: Master List Comprehensions
Create lists using comprehensions. Try with filters, conditions, and transformations.
Nested Lists (2D Lists)
Creating 2D Lists:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]
Accessing Elements:
print(matrix[0]) # [1, 2, 3] (first row)print(matrix[1][2]) # 6 (row 1, column 2)
Iterating:
# Iterate rows:for row in matrix: print(row)# Iterate all elements:for row in matrix: for item in row: print(item, end=" ")
List Best Practices
- Use list comprehensions: They're faster and more readable than append() in loops
- Be careful with copying: Use
.copy()or[:]to avoid reference issues - Check before remove(): Use
if item in list:beforeremove()to avoid errors - Use enumerate(): When you need both index and value:
for i, item in enumerate(mylist): - Avoid modifying during iteration: Create a copy if you need to modify while iterating
- Consider other types: If you don't need mutability, use tuples (faster, less memory)
- Use in for membership:
if x in mylist:is cleaner than checking index
Try It: Advanced List Techniques
Practice nested lists, copying, and combining multiple list operations. Create practical programs!
Next Steps
Now that you've mastered lists, you're ready to explore other important data structures: dictionaries, sets, and tuples – each with unique characteristics and use cases.
Dictionaries, Sets & Tuples
Overview
Python provides several built-in data structures beyond lists. Dictionaries store key-value pairs for fast lookups, sets store unique items with mathematical set operations, and tuples are immutable ordered sequences. Each has distinct characteristics and use cases.
Dictionaries
Dictionary Basics
Dictionaries are unordered collections of key-value pairs. They're perfect for storing related data and enabling fast lookups by key.
Creating Dictionaries:
#Empty dictionary:empty = {}also_empty = dict()# With initial data:person = { "name": "Alice", "age": 30, "city": "Seattle"}# Using dict():person = dict(name="Alice", age=30, city="Seattle")# From list of tuples:items = [("name", "Bob"), ("age", 25)]person = dict(items)
Accessing Values:
person = {"name": "Alice", "age": 30}# Using bracket notation:print(person["name"]) # "Alice"# Using get() (safer - returns None if key doesn't exist):print(person.get("city")) # None (no error)print(person.get("city", "Unknown")) # "Unknown" (default)
Adding/Modifying Items:
person = {"name": "Alice"}# Add new key-value:person["age"] = 30# Modify existing:person["age"] = 31# Update multiple items:person.update({"city": "Seattle", "job": "Engineer"})
Removing Items:
# del - Remove key:del person["city"]# pop() - Remove and return value:age = person.pop("age")# clear() - Remove all items:person.clear()
Try It: Dictionary Basics
Create dictionaries, add/modify/remove items. Practice accessing values with [] and get().
Dictionary Methods
person = {"name": "Alice", "age": 30, "city": "Seattle"}# keys() - Get all keys:keys = person.keys() # dict_keys(['name', 'age', 'city'])# values() - Get all values:values = person.values() # dict_values(['Alice', 30, 'Seattle'])# items() - Get key-value pairs:items = person.items() # dict_items([('name', 'Alice'), ...])# Iterate over dictionary:for key in person: print(f"{key}: {person[key]}")# Better: iterate over items:for key, value in person.items(): print(f"{key}: {value}")# Check if key exists:if "name" in person: print("Name exists")
Try It: Dictionary Methods and Iteration
Use keys(), values(), items(). Iterate over dictionaries in different ways.
Sets
Set Basics
Sets are unordered collections of unique items. They're perfect for removing duplicates and performing mathematical set operations.
Creating Sets:
# Empty set (can't use {} - that's a dict!):empty = set()# With initial values:numbers = {1, 2, 3, 4, 5}fruits = {"apple", "banana", "cherry"}# From list (removes duplicates):numbers = set([1, 2, 2, 3, 3, 3])print(numbers) # {1, 2, 3}# From string:letters = set("hello") # {'h', 'e', 'l', 'o'}
Adding/Removing Elements:
fruits = {"apple", "banana"}# add() - Add single item:fruits.add("cherry")# update() - Add multiple items:fruits.update(["date", "elderberry"])# remove() - Remove (error if not found):fruits.remove("apple")# discard() - Remove (no error if not found):fruits.discard("apple") # Safe even if "apple" not in set# pop() - Remove and return random item:item = fruits.pop()# clear() - Remove all:fruits.clear()
Set Operations
a = {1, 2, 3, 4}b = {3, 4, 5, 6}# Union (all items from both sets):print(a | b) # {1, 2, 3, 4, 5, 6}print(a.union(b)) # Same result# Intersection (items in both sets):print(a & b) # {3, 4}print(a.intersection(b)) # Same result# Difference (items in a but not in b):print(a - b) # {1, 2}print(a.difference(b)) # Same result# Symmetric Difference (items in either set, but not both):print(a ^ b) # {1, 2, 5, 6}print(a.symmetric_difference(b)) # Same result# Subset and Superset:print({1, 2}.issubset({1, 2, 3})) # Trueprint({1, 2, 3}.issuperset({1, 2})) # True
Try It: Work with Sets
Create sets, remove duplicates from lists. Practice set operations like union, intersection, difference.
Tuples
Tuple Basics
Tuples are immutable ordered sequences. Once created, they cannot be modified. Use them for data that shouldn't change.
Creating Tuples:
# Empty tuple:empty = ()also_empty = tuple()# Tuple with items:coordinates = (10, 20)rgb = (255, 128, 0)# Single-item tuple (note the comma!):single = (42,) # Comma is requirednot_tuple = (42) # This is just integer 42# Without parentheses (tuple packing):point = 10, 20 # Creates tuple (10, 20)# From list:my_tuple = tuple([1, 2, 3])
Accessing Elements:
coordinates = (10, 20, 30)# Indexing (same as lists):print(coordinates[0]) # 10print(coordinates[-1]) # 30# Slicing:print(coordinates[1:]) # (20, 30)# Tuple unpacking:x, y, z = coordinatesprint(x, y, z) # 10 20 30
Immutability:
point = (10, 20)# Cannot modify:# point[0] = 15 # ERROR: 'tuple' object does not support item assignment# Cannot add/remove:# point.append(30) # ERROR: no append method# Must create new tuple:point = point + (30,) # (10, 20, 30)
Tuple Methods
Tuples have only two methods (because they're immutable):
numbers = (1, 2, 3, 2, 4, 2, 5)# count() - Count occurrences:count = numbers.count(2) # 3# index() - Find index of first occurrence:idx = numbers.index(4) # 4
When to Use Tuples:
- For data that shouldn't change (coordinates, RGB colors, database records)
- As dictionary keys (lists can't be keys because they're mutable)
- To return multiple values from functions
- Slightly faster and use less memory than lists
Tuple as Dictionary Key:
# Valid - tuples are hashable:locations = { (10, 20): "home", (30, 40): "work"}# Invalid - lists are not hashable:# locations = {[10, 20]: "home"} # ERROR
Try It: Practice Tuples
Create tuples, practice unpacking. Try using tuples as dictionary keys. Compare with lists.
Quick Comparison
| Feature | Dictionary | Set | Tuple |
|---|---|---|---|
| Ordered | Yes (Python 3.7+) | No | Yes |
| Mutable | Yes | Yes | No |
| Duplicates | Keys: No, Values: Yes | No | Yes |
| Indexing | By key | No | By position |
| Use Case | Key-value mapping | Unique items, math operations | Immutable sequences |
| Syntax | {"key": "value"} |
{1, 2, 3} |
(1, 2, 3) |
Try It: Compare All Three
Create programs that use dictionaries, sets, and tuples together. Understand when to use each.
Next Steps
Now that you understand dictionaries, sets, and tuples, you're ready to dive deep into strings – manipulating text with slicing, methods, formatting, and more.
Strings
Overview
Strings are sequences of characters used to represent text. In Python, strings are immutable, meaning once created, they cannot be changed. Python provides a rich set of methods for string manipulation, making text processing powerful and intuitive.
Creating Strings
Different Quote Styles:
# Single quotes:message = 'Hello, World!'# Double quotes:message = "Hello, World!"# Triple quotes (multi-line):message = """This isa multi-linestring"""# Quotes within strings:message1 = "She said, 'Hello!'"message2 = 'He said, "Goodbye!"'
Indexing and Slicing
String Indexing:
text = "Python"# Positive indexing:print(text[0]) # 'P' (first character)print(text[3]) # 'h'# Negative indexing:print(text[-1]) # 'n' (last character)print(text[-2]) # 'o'
String Slicing [start:stop:step]:
text = "Hello, World!"print(text[0:5]) # "Hello" (characters 0-4)print(text[:5]) # "Hello" (from start to 4)print(text[7:]) # "World!" (from 7 to end)print(text[::2]) # "Hlo ol!" (every 2nd char)print(text[::-1]) # "!dlroW ,olleH" (reversed)
Try It: String Indexing and Slicing
Create strings and practice indexing and slicing. Try reversing strings and extracting substrings.
Common String Methods
Case Conversion:
text = "Hello World"print(text.upper()) # "HELLO WORLD"print(text.lower()) # "hello world"print(text.capitalize()) # "Hello world"print(text.title()) # "Hello World"print(text.swapcase()) # "hELLO wORLD"
Checking String Content:
text = "Hello123"print(text.isalpha()) # False (has numbers)print(text.isdigit()) # False (has letters)print(text.isalnum()) # True (alphanum only)print(text.islower()) # Falseprint(text.isupper()) # Falseprint(" ".isspace()) # Trueprint("123".isdigit()) # True
Searching and Counting:
text = "Hello, World! Hello, Python!"# find() - Return index of first occurrence (-1 if not found):print(text.find("World")) # 7print(text.find("xyz")) # -1# index() - Like find() but raises error if not found:print(text.index("World")) # 7# count() - Count occurrences:print(text.count("Hello")) # 2# startswith() and endswith():print(text.startswith("Hello")) # Trueprint(text.endswith("Python!")) # True
Replacing and Splitting:
text = "Hello, World!"# replace() - Replace substrings:new = text.replace("World", "Python")print(new) # "Hello, Python!"# split() - Split into list:words = text.split(", ")print(words) # ['Hello', 'World!']# join() - Join list into string:words = ["Hello", "World"]text = " ".join(words)print(text) # "Hello World"
Trimming Whitespace:
text = " Hello "print(text.strip()) # "Hello" (both sides)print(text.lstrip()) # "Hello " (left side)print(text.rstrip()) # " Hello" (right side)
Try It: Practice String Methods
Use various string methods for case conversion, searching, replacing, and splitting. Build text processors!
String Formatting
1. f-strings (Python 3.6+) - Recommended:
name = "Alice"age = 30price = 19.99# Basic f-string:message = f"My name is {name} and I'm {age} years old"# Expressions inside {}:print(f"Next year I'll be {age + 1}")print(f"5 squared is {5**2}")# Formatting numbers:print(f"Price: ${price:.2f}") # $19.99 (2 decimals)print(f"Price: ${price:.0f}") # $20 (no decimals)
2. .format() Method:
# Positional:message = "My name is {} and I'm {} years old".format(name, age)# By index:message = "{0} is {1} years old. {0} loves Python!".format(name, age)# By name:message = "{name} is {age} years old".format(name="Bob", age=25)
3. % Operator (Old Style):
name = "Alice"age = 30message = "My name is %s and I'm %d years old" % (name, age)# %s = string, %d = integer, %f = float
Try It: Master String Formatting
Practice f-strings, .format(), and % operator. Format numbers, expressions, and create templates.
Escape Characters
Use backslash \ to insert special characters in strings.
# Newline:print("Hello\nWorld") # World on new line# Tab:print("Name:\tAlice") # Adds tab space# Backslash:print("C:\\Users\\File") # C:\Users\File# Quotes within quotes:print("She said, \"Hello!\"") # She said, "Hello!"print('It\'s a nice day') # It's a nice day# Raw strings (ignore escape characters):path = r"C:\Users\name\file.txt" # Backslashes not escapedprint(path) # C:\Users\name\file.txt
Common Escape Sequences:
\n— Newline\t— Tab\\— Backslash\'— Single quote\"— Double quote\r— Carriage return\b— Backspace
String Operations
Concatenation:
# Using +:greeting = "Hello" + " " + "World"print(greeting) # "Hello World"# Using +=:text = "Hello"text += " World"print(text) # "Hello World"
Repetition:
print("=" * 20) # ====================print("Hi! " * 3) # Hi! Hi! Hi!
Membership:
text = "Hello, World!"print("World" in text) # Trueprint("Python" in text) # Falseprint("Python" not in text) # True
Length:
text = "Hello, World!"print(len(text)) # 13
Try It: String Operations
Practice concatenation, repetition, membership testing. Create text patterns and decorators.
String Immutability
Strings cannot be modified in place. Any operation that appears to modify a string creates a new string.
text = "Hello"# Cannot modify:# text[0] = "h" # ERROR: 'str' object does not support item assignment# Must create new string:text = "h" + text[1:] # "hello"# Or:text = text.replace("H", "h") # "hello"
Practical String Examples
Example 1: Validate Email
email = "user@example.com"if "@" in email and "." in email.split("@")[1]: print("Valid email format")
Example 2: Format Names
name = "john doe"formatted = name.title() # "John Doe"
Example 3: Parse CSV Data
data = "Alice,30,Engineer"name, age, job = data.split(",")print(f"Name: {name}, Age: {age}, Job: {job}")
Example 4: Clean User Input
user_input = " Hello World! "clean = user_input.strip().lower()print(clean) # "hello world!"
Try It: Build String Programs
Create practical programs: text validators, formatters, parsers. Combine multiple string methods!
String Best Practices
- Use f-strings: They're fast, readable, and the modern way to format strings
- Use join() for concatenation in loops: Much faster than += for building long strings
- Use raw strings for paths:
r"C:\path\to\file"avoids escape issues - Check before find(): Use
find()(returns -1) instead ofindex()(raises error) for searches - Use strip() on user input: Remove accidental whitespace
- Remember immutability: Methods like replace() return new strings, don't modify original
- Use in for substring checking:
if "test" in string:is cleaner thanfind()
Next Steps
Now that you've mastered strings, you're ready to learn about recursion – a powerful programming technique where functions call themselves to solve problems.
Recursion
Overview
Recursion is a programming technique where a function calls itself to solve a problem by breaking it down into smaller, similar sub-problems. A recursive function must have a base case (stopping condition) and a recursive case (where the function calls itself). Recursion is particularly elegant for problems with a naturally recursive structure like tree traversal, factorials, and divide-and-conquer algorithms.
The Basic Concept
Anatomy of a Recursive Function:
def recursive_function(parameters): # Base case - stopping condition if base_condition: return base_value # Recursive case - function calls itself else: return recursive_function(modified_parameters)
Simple Example: Countdown
def countdown(n): # Base case: stop when n reaches 0 if n <= 0: print("Blastoff!") # Recursive case: print and call with n-1 else: print(n) countdown(n - 1)countdown(5)# Output:# 5# 4# 3# 2# 1# Blastoff!
How It Works:
Each function call creates a new "instance" on the call stack. When the base case is reached, the stack "unwinds" as each function returns to its caller.
Try It: Simple Recursive Functions
Create basic recursive functions like countdown or count-up. Understand the base and recursive cases.
Classic Recursive Examples
1. Factorial
Factorial of n (n!) = n × (n-1) × (n-2) × ... × 1
def factorial(n): """Calculate factorial of n recursively""" # Base case: 0! = 1 and 1! = 1 if n <= 1: return 1 # Recursive case: n! = n × (n-1)! else: return n * factorial(n - 1)print(factorial(5)) # 120 (5 × 4 × 3 × 2 × 1)# Call stack visualization:# factorial(5) = 5 * factorial(4)# = 5 * (4 * factorial(3))# = 5 * (4 * (3 * factorial(2)))# = 5 * (4 * (3 * (2 * factorial(1))))# = 5 * (4 * (3 * (2 * 1)))# = 120
2. Fibonacci Sequence
Each number is the sum of the two preceding ones: 0, 1, 1, 2, 3, 5, 8, 13...
def fibonacci(n): """Return the nth Fibonacci number""" # Base cases if n <= 0: return 0 elif n == 1: return 1 # Recursive case: fib(n) = fib(n-1) + fib(n-2) else: return fibonacci(n - 1) + fibonacci(n - 2)print(fibonacci(7)) # 13# Sequence: 0, 1, 1, 2, 3, 5, 8, 13
3. Sum of List
def sum_list(numbers): """Sum all numbers in a list recursively""" # Base case: empty list if not numbers: return 0 # Recursive case: first element + sum of rest else: return numbers[0] + sum_list(numbers[1:])print(sum_list([1, 2, 3, 4, 5])) # 15
4. Power Function
def power(base, exp): """Calculate base^exp recursively""" # Base case: any number to power 0 is 1 if exp == 0: return 1 # Recursive case: base^exp = base × base^(exp-1) else: return base * power(base, exp - 1)print(power(2, 5)) # 32 (2^5)
Try It: Classic Recursion Problems
Implement factorial, Fibonacci, sum, and power functions recursively. Trace the call stack!
Advanced Recursive Examples
1. Binary Search
Efficiently search a sorted list by repeatedly dividing the search interval in half:
def binary_search(arr, target, low, high): """Search for target in sorted array using recursion""" # Base case: element not found if low > high: return -1 # Find middle mid = (low + high) // 2 # Found it! if arr[mid] == target: return mid # Target is in left half elif arr[mid] > target: return binary_search(arr, target, low, mid - 1) # Target is in right half else: return binary_search(arr, target, mid + 1, high)numbers = [1, 3, 5, 7, 9, 11, 13, 15]index = binary_search(numbers, 7, 0, len(numbers) - 1)print(f"Found at index: {index}") # Found at index: 3
2. Palindrome Checker
def is_palindrome(text): """Check if text is a palindrome recursively""" # Remove spaces and convert to lowercase text = text.replace(" ", "").lower() # Base cases: 0 or 1 character is always palindrome if len(text) <= 1: return True # Recursive case: first and last match, and middle is palindrome if text[0] == text[-1]: return is_palindrome(text[1:-1]) else: return Falseprint(is_palindrome("racecar")) # Trueprint(is_palindrome("A man a plan a canal Panama")) # True
3. Greatest Common Divisor (GCD)
Using Euclidean algorithm:
def gcd(a, b): """Find GCD of two numbers using Euclid's algorithm""" # Base case: when b is 0, GCD is a if b == 0: return a # Recursive case: gcd(a, b) = gcd(b, a % b) else: return gcd(b, a % b)print(gcd(48, 18)) # 6
Try It: Advanced Recursive Algorithms
Implement binary search, palindrome checker, and GCD. Understand divide-and-conquer approach.
Recursion vs Iteration
Same Problem, Two Approaches:
# RECURSIVE factorial:def factorial_recursive(n): if n <= 1: return 1 return n * factorial_recursive(n - 1)# ITERATIVE factorial:def factorial_iterative(n): result = 1 for i in range(2, n + 1): result *= i return result
Pros and Cons:
Recursion Advantages:
- More elegant and easier to understand for naturally recursive problems
- Cleaner code with less boilerplate
- Natural fit for tree/graph traversal and divide-and-conquer
Recursion Disadvantages:
- Uses more memory (call stack)
- Slower due to function call overhead
- Risk of stack overflow with deep recursion
- Can be harder to debug
When to Use Recursion:
- Problem has a naturally recursive structure (trees, graphs)
- Code clarity is more important than performance
- Recursion depth is limited and reasonable
- Examples: tree traversal, parsing, backtracking algorithms
When to Use Iteration:
- Performance is critical
- Deep recursion could cause stack overflow
- Simple sequential processing
- Examples: summing arrays, searching lists, counting
Common Pitfalls and Solutions
Pitfall 1: Missing Base Case
# WRONG - infinite recursion:def bad_countdown(n): print(n) bad_countdown(n - 1) # No base case!# CORRECT:def good_countdown(n): if n <= 0: # Base case return print(n) good_countdown(n - 1)
Pitfall 2: Not Moving Toward Base Case
# WRONG - never reaches base case:def bad_function(n): if n == 0: return bad_function(n) # Calls with same value!# CORRECT:def good_function(n): if n == 0: return good_function(n - 1) # Moves toward base case
Pitfall 3: Inefficient Fibonacci (Repeated Calculations)
# INEFFICIENT - recalculates same values many times:def fib_slow(n): if n <= 1: return n return fib_slow(n-1) + fib_slow(n-2)# EFFICIENT - with memoization:def fib_fast(n, memo={}): if n in memo: return memo[n] if n <= 1: return n memo[n] = fib_fast(n-1, memo) + fib_fast(n-2, memo) return memo[n]
Pitfall 4: Stack Overflow
Python has a recursion limit (usually 1000). For deep recursion:
import sys# Check current limit:print(sys.getrecursionlimit()) # Usually 1000# Increase limit (use cautiously!):sys.setrecursionlimit(2000)# Better: use iteration for deep recursion
Try It: Debug Recursive Functions
Fix broken recursive functions. Experiment with memoization. Test recursion limits.
Recursion Best Practices
- Always have a base case: Ensure recursion eventually stops
- Move toward base case: Each recursive call must get closer to the base case
- Keep it simple: Recursive functions should be short and clear
- Use memoization: Cache results to avoid repeated calculations
- Consider iteration: If recursion is deep or complex, iteration might be better
- Add docstrings: Explain what the function does and what the base case is
- Test with small inputs: Start with simple cases before complex ones
- Trace execution: Use print statements or debugger to understand flow
Try It: Recursion Practice Problems
Challenge yourself: reverse a string, flatten nested lists, or traverse a directory tree recursively!
Summary
- Recursion: Function calling itself
- Base Case: Condition that stops recursion
- Recursive Case: Function calls itself with modified input
- Call Stack: Each call creates a new frame on the stack
- Every recursive function MUST have a base case
- Progress must be made toward the base case
- Recursion uses more memory than iteration
- Some problems are naturally recursive (trees, graphs)
- Use memoization for optimization when needed
Congratulations!
You've completed the Python tutorial! You've learned about Python basics, data types, control flow, functions, data structures, and advanced concepts like recursion. You now have the foundation to build real-world Python applications.
Next Steps:
- Practice with coding challenges on platforms like LeetCode, HackerRank, or CodeWars
- Build projects: web apps (Flask/Django), data analysis (Pandas), automation scripts
- Learn libraries relevant to your interests: NumPy, Matplotlib, TensorFlow, etc.
- Contribute to open-source Python projects
- Keep coding every day!
Comments
Comments are notes in your code that Python ignores during execution. They're essential for documenting your code and making it understandable.
Single-Line Comments
Use the hash symbol
#to create a single-line comment. Everything after#on that line is ignored.# This is a commentx = 5 # This is also a comment (inline)Multi-Line Comments
Python doesn't have a specific multi-line comment syntax, but you can use multiple
#symbols or triple quotes (which create multi-line strings that can serve as comments)."""This is a multi-line comment.It can span several lines.Useful for documentation."""Best Practices for Comments
# increment xforx = x + 1