Python, renowned for its readability and simplicity, provides a rich set of built-in functions that streamline coding and enhance productivity. These functions are readily available without requiring any imports and perform common tasks, making everyday programming more efficient.
From handling basic input and output to performing type conversions and mathematical operations, Python's built-in functions form the bedrock of many applications. Understanding how to effectively use them is crucial for any Python developer, as they contribute significantly to writing concise, clean, and Pythonic code.
What are Functions?
In Python, a function is a block of organized, reusable code that is used to perform a single, related action. Functions provide better modularity for your application and a high degree of code reusing. They allow you to break down large programs into smaller, manageable, and organized tasks, which makes your code easier to read, debug, and maintain.
Function Syntax (General)
Functions in Python are defined using the def
keyword, followed by the function name, a set of parentheses ()
that may contain parameters, and a colon :
. The function's body is indented below the definition line.
def function_name(parameters):
"""Docstring: Optional documentation string for the function."""
# Function body - code to be executed
statement_1
statement_2
# ...
return value # Optional: returns a value from the function
Parameters vs. Arguments
While often used interchangeably, 'parameters' and 'arguments' have distinct meanings in the context of functions:
-
Parameters: These are the names listed in the function definition. They are placeholders for the values that the function expects to receive when it's called.
def greet(name): # 'name' is a parameter print(f"Hello, {name}!")
-
Arguments: These are the actual values passed to the function when it is called. The arguments are assigned to the corresponding parameters.
greet("Alice") # "Alice" is an argument greet("Bob") # "Bob" is an argument
Return Values
Functions can optionally return a value to the caller. The return
statement is used for this purpose. When Python encounters a return
statement, the function immediately terminates, and the value specified after return
is sent back to the point where the function was called. If no return
statement is used, or if return
is used without an argument, the function returns None
by default.
def add_numbers(a, b):
sum_result = a + b
return sum_result # Returns the calculated sum
result = add_numbers(5, 3)
print(result) # Output: 8
def say_hello():
print("Hello!")
This function returns None implicitly
none_value = say_hello()
print(none_value) # Output: Hello!
# Output: None
Basic Data Types in Python
- Integers (int): Whole numbers, positive or negative, without a decimal point. Example:
age = 30
,temperature = -5
- Floats (float): Real numbers with a decimal point. Example:
price = 19.99
,pi = 3.14159
- Strings (str): Sequences of characters, enclosed in single or double quotes. Example:
name = "Alice"
,message = 'Hello, World!'
- Booleans (bool): Represents truth values, either True or False. Example:
is_active = True
,is_logged_in = False
- Lists (list): Ordered, mutable collections of items. Enclosed in square brackets []. Example:
fruits = ["apple", "banana", "cherry"]
,numbers = [1, 2, 3, 4]
- Tuples (tuple): Ordered, immutable collections of items. Enclosed in parentheses (). Example:
coordinates = (10.0, 20.0)
,colors = ("red", "green", "blue")
- Dictionaries (dict): Unordered, mutable collections of key-value pairs. Enclosed in curly braces {}. Example:
person = {"name": "Bob", "age": 25}
,settings = {"debug": True, "port": 8080}
- Sets (set): Unordered collections of unique items. Enclosed in curly braces {} (or set() for an empty set). Example:
unique_numbers = {1, 2, 3, 4, 1}
(results in {1, 2, 3, 4}),vowels = {'a', 'e', 'i', 'o', 'u'}
Input/Output & Basic Utilities
print()
The print()
function outputs text or values to the console (standard output). It's one of the most frequently used functions for displaying information during program execution.
- Parameters:
*objects
: One or more objects to be printed. They are converted to string representation.sep=' '
: (Optional) A string inserted between objects, if multiple are given. Defaults to a single space.end='\n'
: (Optional) A string appended after the last object. Defaults to a newline character, causing subsequent prints to appear on a new line.file=sys.stdout
: (Optional) A file-like object (stream) where the output will be written.flush=False
: (Optional) IfTrue
, the stream is forcibly flushed.
- Return Value:
None
- Usage Examples:
print("Hello, World!") name = "Alice" age = 30 print("Name:", name, "Age:", age) print("Item 1", "Item 2", sep=" | ", end=" --END--\n") print("This is on a new line.")
- Activity:
- Print your name and favorite hobby on a single line.
- Print three different numbers, separated by a comma.
input()
The input()
function reads a line of text from the user (standard input, typically the keyboard) and returns it as a string. It's essential for creating interactive programs.
- Parameters:
prompt
: (Optional) A string that is displayed to the user before they enter their input. It does not include a trailing newline.
- Return Value: A string containing the user's input.
- Usage Examples:
user_name = input("Enter your name: ") print("Hello,", user_name) age_str = input("How old are you? ") Input is always a string, convert to int for numerical operations age = int(age_str) print(f"You will be {age + 1} next year.")
- Activity:
- Ask the user for their favorite color and print a message like "Your favorite color is [color]!".
- Prompt the user to enter two numbers, then print their sum. Remember to convert input to numbers.
len()
The len()
function returns the length (the number of items) of an object. It works on sequences (like strings, lists, tuples) and collections (like dictionaries, sets).
- Parameters:
object
: The object whose length is to be returned.
- Return Value: An integer representing the number of items.
- Usage Examples:
my_string = "Python" print(len(my_string)) # Output: 6 my_list = [10, 20, 30, 40, 50] print(len(my_list)) # Output: 5 my_dict = {"a": 1, "b": 2, "c": 3} print(len(my_dict)) # Output: 3
- Activity:
- Create a list of your favorite fruits and print the number of fruits in the list.
- Ask the user to type a sentence and print the number of characters (including spaces) in the sentence.
type()
The type()
function returns the type of an object. This is useful for debugging and for understanding how data is stored and handled in Python.
- Parameters:
object
: The object whose type is to be returned.
- Return Value: The type object of the given
object
. - Usage Examples:
num = 10 print(type(num)) # Output: <class 'int'> text = "hello" print(type(text)) # Output: <class 'str'> my_list = [1, 2, 3] print(type(my_list)) # Output: <class 'list'> is_true = True print(type(is_true)) # Output: <class 'bool'>
- Activity:
- Declare a variable with a float value and print its type.
- Declare a variable that holds a dictionary and print its type.
id()
The id()
function returns the "identity" of an object. This is an integer that is guaranteed to be unique and constant for this object during its lifetime. It essentially refers to the object's memory address.
- Parameters:
object
: The object whose identity is to be returned.
- Return Value: An integer representing the object's memory address.
- Usage Examples:
a = 10 b = 10 print(id(a)) # Often the same as id(b) for small integers due to optimization print(id(b)) list1 = [1, 2, 3] list2 = [1, 2, 3] print(id(list1)) # Always different from id(list2) as they are distinct objects print(id(list2)) x = "python" print(id(x)) x = "Python" # x now refers to a new string object print(id(x))
- Activity:
- Create two string variables with the same content (e.g.,
"hello"
) and print theirid()
s. Observe if they are the same or different. - Create two list variables with the same content (e.g.,
[1, 2]
) and print theirid()
s. Explain why they are always different.
- Create two string variables with the same content (e.g.,
Type Conversion Functions
int()
The int()
function converts a specified value into an integer number. It can convert floats by truncating the decimal part, or strings if they represent valid integer numbers. An optional base can be specified for string conversion.
- Parameters:
x
: (Optional) A number or a string that can be converted to an integer. If not provided, returns0
.base
: (Optional) An integer representing the base of the number in the stringx
(e.g., 2 for binary, 10 for decimal, 16 for hexadecimal). Only applicable ifx
is a string. Defaults to 10.
- Return Value: An integer.
- Usage Examples:
print(int(3.14)) # Output: 3 print(int(-5.9)) # Output: -5 print(int("100")) # Output: 100 print(int("101", 2)) # Output: 5 (binary 101 is decimal 5) print(int("3.14")) # Raises ValueError print(int("hello")) # Raises ValueError
float()
The float()
function converts a specified value into a floating-point number. It can convert integers or strings if they represent valid floating-point numbers.
- Parameters:
x
: (Optional) An integer or a string that can be converted to a float. If not provided, returns0.0
.
- Return Value: A floating-point number.
- Usage Examples:
print(float(10)) # Output: 10.0 print(float("3.14159")) # Output: 3.14159 print(float("-0.5")) # Output: -0.5 print(float("hello")) # Raises ValueError
str()
The str()
function converts a specified value into a string representation. It's useful for converting numbers, lists, dictionaries, or any other object into a string for display or manipulation.
- Parameters:
object
: The object to be converted to a string.
- Return Value: A string.
- Usage Examples:
print(str(123)) # Output: "123" print(str(3.14)) # Output: "3.14" print(str([1, 2, 3])) # Output: "[1, 2, 3]" print(str({'a': 1, 'b': 2})) # Output: "{'a': 1, 'b': 2}" print("The number is " + str(42)) # Output: "The number is 42"
bool()
The bool()
function converts a specified value into a boolean value (True
or False
). In Python, certain values are considered "falsy" (evaluate to False
), and all others are "truthy" (evaluate to True
).
- Parameters:
x
: (Optional) The value to be converted. If omitted, returnsFalse
.
- Return Value:
True
orFalse
. - Usage Examples:
print(bool(1)) # Output: True print(bool(0)) # Output: False print(bool("hello")) # Output: True print(bool("")) # Output: False (empty string is falsy) print(bool([])) # Output: False (empty list is falsy) print(bool([1, 2])) # Output: True print(bool(None)) # Output: False print(bool(0.0)) # Output: False
list()
The list()
function creates a new list. If an iterable is provided, it converts that iterable into a list. If no argument is given, it creates an empty list.
- Parameters:
iterable
: (Optional) An iterable object (e.g., tuple, string, set) to convert into a list.
- Return Value: A new list.
- Usage Examples:
print(list()) # Output: [] (empty list) print(list("hello")) # Output: ['h', 'e', 'l', 'l', 'o'] print(list((1, 2, 3))) # Output: [1, 2, 3] (from a tuple) print(list({10, 20, 30})) # Output: [10, 20, 30] (order may vary from a set) my_range = range(5) print(list(my_range)) # Output: [0, 1, 2, 3, 4]
tuple()
The tuple()
function creates a new tuple. If an iterable is provided, it converts that iterable into a tuple. If no argument is given, it creates an empty tuple.
- Parameters:
iterable
: (Optional) An iterable object (e.g., list, string, set) to convert into a tuple.
- Return Value: A new tuple.
- Usage Examples:
print(tuple()) # Output: () (empty tuple) print(tuple("world")) # Output: ('w', 'o', 'r', 'l', 'd') print(tuple([4, 5, 6])) # Output: (4, 5, 6) (from a list) print(tuple({100, 200})) # Output: (100, 200) (order may vary from a set)
set()
The set()
function creates a new set. If an iterable is provided, it converts that iterable into a set, automatically removing duplicate elements. If no argument is given, it creates an empty set.
- Parameters:
iterable
: (Optional) An iterable object to convert into a set.
- Return Value: A new set.
- Usage Examples:
print(set()) # Output: set() (empty set) print(set([1, 2, 2, 3])) # Output: {1, 2, 3} (duplicates removed) print(set("Mississippi")) # Output: {'M', 'i', 's', 'p'} (order not guaranteed) print(set((5, 5, 6, 7))) # Output: {5, 6, 7} (from a tuple)
dict()
The dict()
function creates a new dictionary. It can be initialized in several ways:
- With keyword arguments (
key=value
pairs). - From an iterable of key-value pairs (e.g., a list of tuples).
- From another mapping object (e.g., another dictionary).
- Parameters:
**kwargs
: (Optional) Keyword arguments where keys are the dictionary keys and values are the dictionary values.mapping
: (Optional) Another dictionary or a mapping object.iterable
: (Optional) An iterable of key-value pairs (e.g., a list of 2-item tuples).
- Return Value: A new dictionary.
- Usage Examples:
print(dict()) # Output: {} (empty dictionary) print(dict(name="Alice", age=30)) # Output: {'name': 'Alice', 'age': 30} print(dict([('x', 1), ('y', 2)])) # Output: {'x': 1, 'y': 2} (from list of tuples) print(dict(zip(['a', 'b'], [1, 2]))) # Output: {'a': 1, 'b': 2} (from zip object) my_data = {'color': 'blue', 'size': 'M'} print(dict(my_data)) # Output: {'color': 'blue', 'size': 'M'} (copy from another dict)
Mathematical & Numeric Functions
abs()
The abs()
function returns the absolute value of a number. The absolute value of a number is its distance from zero, always a non-negative value.
- Parameters:
number
: An integer, float, or complex number.
- Return Value: The absolute value of the number. For a complex number, it returns its magnitude.
- Usage Examples:
print(abs(-5)) # Output: 5 print(abs(10)) # Output: 10 print(abs(-3.14)) # Output: 3.14 print(abs(0)) # Output: 0 print(abs(3 - 4j)) # Output: 5.0 (magnitude of a complex number sqrt(3^2 + (-4)^2))
round()
The round()
function rounds a number to a specified number of decimal places. If no number of decimal places is specified, it returns the nearest integer. For numbers exactly halfway between two integers, it rounds to the nearest even integer (round half to even).
- Parameters:
number
: The number to be rounded (integer or float).ndigits
: (Optional) The number of decimal places to round to. If omitted, returns an integer.
- Return Value: An integer if
ndigits
is omitted, otherwise a float. - Usage Examples:
print(round(3.14159)) # Output: 3 (rounds to nearest integer) print(round(3.7)) # Output: 4 print(round(2.5)) # Output: 2 (rounds to nearest even) print(round(3.5)) # Output: 4 (rounds to nearest even) print(round(3.14159, 2)) # Output: 3.14 print(round(10.456, 1)) # Output: 10.5
min()
The min()
function returns the smallest item in an iterable or the smallest of two or more arguments.
- Parameters:
iterable
: An iterable (e.g., list, tuple, string) containing comparable items.*args
: Two or more arguments to compare.key
: (Optional) A function to specify a custom sort order.default
: (Optional) A value to return if the iterable is empty.
- Return Value: The smallest item.
- Usage Examples:
print(min(1, 5, -2, 8)) # Output: -2 print(min([10, 20, 5, 30])) # Output: 5 print(min("banana", "apple", "zebra")) # Output: "apple" (lexicographical comparison) print(min("hello")) # Output: 'e' (smallest character by ASCII value) print(min([], default=0)) # Output: 0 (if iterable is empty) print(min("python", key=len)) # Output: "python" (length is 6, only one item) print(min("py", "java", "csharp", key=len)) # Output: "py" (smallest length)
max()
The max()
function returns the largest item in an iterable or the largest of two or more arguments.
- Parameters:
iterable
: An iterable (e.g., list, tuple, string) containing comparable items.*args
: Two or more arguments to compare.key
: (Optional) A function to specify a custom sort order.default
: (Optional) A value to return if the iterable is empty.
- Return Value: The largest item.
- Usage Examples:
print(max(1, 5, -2, 8)) # Output: 8 print(max([10, 20, 5, 30])) # Output: 30 print(max("banana", "apple", "zebra")) # Output: "zebra" (lexicographical comparison) print(max("hello")) # Output: 'o' (largest character by ASCII value) print(max([], default=0)) # Output: 0 (if iterable is empty) print(max("py", "java", "csharp", key=len)) # Output: "csharp" (largest length)
sum()
The sum()
function sums the items of an iterable from left to right and returns the total. The items must be numbers.
- Parameters:
iterable
: An iterable of numbers (integers, floats).start
: (Optional) An initial value to which the items of the iterable are added. Defaults to 0.
- Return Value: The sum of the numbers.
- Usage Examples:
numbers = [1, 2, 3, 4, 5] print(sum(numbers)) # Output: 15 floats = [1.5, 2.5, 3.0] print(sum(floats)) # Output: 7.0 print(sum(range(1, 11))) # Output: 55 (sum of numbers from 1 to 10) print(sum([10, 20], 5)) # Output: 35 (10 + 20 + 5)
Iteration & Sequence Functions
range()
The range()
function generates a sequence of numbers, which is commonly used for iterating a specific number of times in loops. It returns an immutable sequence object.
- Parameters:
stop
: An integer specifying when to stop. The sequence will go up to, but not include, this number.start
: (Optional) An integer specifying when to start. Defaults to 0.step
: (Optional) An integer specifying the increment (or decrement) between numbers. Defaults to 1.
- Return Value: A
range
object. - Usage Examples:
# range(stop) - starts from 0, increments by 1 for i in range(5): print(i, end=" ") # Output: 0 1 2 3 4 print() range(start, stop) for i in range(2, 7): print(i, end=" ") # Output: 2 3 4 5 6 print() range(start, stop, step) for i in range(1, 10, 2): print(i, end=" ") # Output: 1 3 5 7 9 print() Decrementing range for i in range(5, 0, -1): print(i, end=" ") # Output: 5 4 3 2 1 print() Converting to a list print(list(range(3))) # Output: [0, 1, 2]
enumerate()
The enumerate()
function adds a counter to an iterable and returns it as an enumerate object. This is often used when you need both the index and the value of items in a loop.
- Parameters:
iterable
: Any object that supports iteration.start
: (Optional) The index number from which the counter is to be started. Defaults to 0.
- Return Value: An
enumerate
object (an iterator that yields pairs of (index, item)). - Usage Examples:
fruits = ["apple", "banana", "cherry"] for index, fruit in enumerate(fruits): print(f"Index {index}: {fruit}") Output: Index 0: apple Index 1: banana Index 2: cherry for index, fruit in enumerate(fruits, start=1): print(f"Item No. {index}: {fruit}") Output: Item No. 1: apple Item No. 2: banana Item No. 3: cherry Converting to a list of tuples print(list(enumerate(fruits))) # Output: [(0, 'apple'), (1, 'banana'), (2, 'cherry')]
zip()
The zip()
function takes two or more iterables and aggregates their elements into a single iterable of tuples. The i-th tuple contains the i-th element from each of the input iterables. It stops when the shortest input iterable is exhausted.
- Parameters:
*iterables
: Two or more iterable objects.
- Return Value: A
zip
object (an iterator that yields tuples). - Usage Examples:
names = ["Alice", "Bob", "Charlie"] ages = [25, 30, 35] occupations = ["Engineer", "Artist", "Doctor"] for name, age in zip(names, ages): print(f"{name} is {age} years old.") Output: Alice is 25 years old. Bob is 30 years old. Charlie is 35 years old. Zipping three iterables for name, age, occ in zip(names, ages, occupations): print(f"{name} ({age}) is a {occ}.") Output: Alice (25) is an Engineer. Bob (30) is an Artist. Charlie (35) is a Doctor. Zipping with unequal lengths (stops at shortest) colors = ["red", "green", "blue"] codes = [101, 102] zipped_data = list(zip(colors, codes)) print(zipped_data) # Output: [('red', 101), ('green', 102)] Unzipping (using *) zipped_tuples = [('A', 1), ('B', 2), ('C', 3)] letters, numbers = zip(*zipped_tuples) print(letters) # Output: ('A', 'B', 'C') print(numbers) # Output: (1, 2, 3)
map()
The map()
function applies a given function to each item of an iterable (or multiple iterables) and returns an iterator that yields the results. It's a concise way to perform transformations on sequences.
- Parameters:
function
: The function to apply to each item.iterable
: One or more iterable objects whose items will be passed to the function.
- Return Value: A
map
object (an iterator). - Usage Examples:
# Applying a function to a single iterable numbers = [1, 2, 3, 4] squared_numbers = map(lambda x: x * x, numbers) print(list(squared_numbers)) # Output: [1, 4, 9, 16] Using a defined function def to_upper(s): return s.upper() words = ["hello", "world"] upper_words = map(to_upper, words) print(list(upper_words)) # Output: ['HELLO', 'WORLD'] Applying a function to multiple iterables num1 = [1, 2, 3] num2 = [4, 5, 6] sums = map(lambda x, y: x + y, num1, num2) print(list(sums)) # Output: [5, 7, 9]
filter()
The filter()
function constructs an iterator from elements of an iterable for which a function returns true. It's used to select items based on a condition.
- Parameters:
function
: A function that tests if each element of an iterable returns true or false. IfNone
, the identity function is used (elements that are "falsy" are removed).iterable
: An iterable object.
- Return Value: A
filter
object (an iterator). - Usage Examples:
# Filtering even numbers numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] even_numbers = filter(lambda x: x % 2 == 0, numbers) print(list(even_numbers)) # Output: [2, 4, 6, 8, 10] Filtering non-empty strings words = ["apple", "", "banana", None, "cherry", ""] valid_words = filter(None, words) # None as function checks for truthiness print(list(valid_words)) # Output: ['apple', 'banana', 'cherry'] Filtering based on a custom function def is_long_word(word): return len(word) > 5 sentence = ["hello", "world", "python", "programming", "is", "fun"] long_words = filter(is_long_word, sentence) print(list(long_words)) # Output: ['python', 'programming']
sorted()
The sorted()
function returns a new sorted list from the items in an iterable. It does not modify the original iterable.
- Parameters:
iterable
: An iterable (e.g., list, tuple, string, set) to be sorted.key
: (Optional) A function to be called on each list element prior to making comparisons.reverse
: (Optional) A boolean value. IfTrue
, the list elements are sorted in descending order. Defaults toFalse
(ascending).
- Return Value: A new sorted
list
. - Usage Examples:
numbers = [3, 1, 4, 1, 5, 9, 2, 6] sorted_numbers = sorted(numbers) print(sorted_numbers) # Output: [1, 1, 2, 3, 4, 5, 6, 9] print(numbers) # Output: [3, 1, 4, 1, 5, 9, 2, 6] (original unchanged) words = ["banana", "apple", "cherry"] sorted_words_desc = sorted(words, reverse=True) print(sorted_words_desc) # Output: ['cherry', 'banana', 'apple'] Sorting by length using a key function words_by_length = sorted(words, key=len) print(words_by_length) # Output: ['apple', 'banana', 'cherry'] (or ['cherry', 'banana', 'apple'] if len is equal) Sorting a list of tuples by the second element data = [('Alice', 30), ('Bob', 25), ('Charlie', 35)] sorted_by_age = sorted(data, key=lambda item: item[1]) print(sorted_by_age) # Output: [('Bob', 25), ('Alice', 30), ('Charlie', 35)]
reversed()
The reversed()
function returns a reverse iterator. It does not create a reversed copy of the sequence in memory, making it memory-efficient for large sequences. It works on objects that implement the reversed()
method or support the sequence protocol (len()
and getitem()
).
- Parameters:
seq
: A sequence object (e.g., list, tuple, string) or an object that implementsreversed()
.
- Return Value: A
reverse iterator
. - Usage Examples:
my_list = [1, 2, 3, 4, 5] reversed_list_iter = reversed(my_list) print(list(reversed_list_iter)) # Output: [5, 4, 3, 2, 1] my_string = "Python" reversed_string_iter = reversed(my_string) print("".join(list(reversed_string_iter))) # Output: nohtyP my_tuple = (10, 20, 30) for item in reversed(my_tuple): print(item, end=" ") # Output: 30 20 10 print()
all()
The all()
function returns True
if all elements of an iterable are true (or if the iterable is empty). Otherwise, it returns False
.
- Parameters:
iterable
: An iterable object.
- Return Value: A boolean value.
- Usage Examples:
print(all([True, True, False])) # Output: False print(all([True, True, True])) # Output: True print(all([0, 1, 2])) # Output: False (0 is falsy) print(all([1, 2, 3])) # Output: True print(all([])) # Output: True (empty iterable is considered all true) print(all("")) # Output: True (empty string is considered all true) print(all([True, 1, "hello"])) # Output: True
any()
The any()
function returns True
if any element of an iterable is true. If the iterable is empty, it returns False
. If at least one element is true, it short-circuits and returns True
immediately.
- Parameters:
iterable
: An iterable object.
- Return Value: A boolean value.
- Usage Examples:
print(any([True, False, False])) # Output: True print(any([False, False, False]))# Output: False print(any([0, "", None])) # Output: False (all elements are falsy) print(any([0, 1, False])) # Output: True (1 is truthy) print(any([])) # Output: False (empty iterable) print(any("hello")) # Output: True (non-empty string is truthy) print(any([0, "", "Hi"])) # Output: True ("Hi" is truthy)
Object-Oriented Programming (OOP) Concepts
Core OOP Concepts
Classes
A class is a blueprint or a template for creating objects. It defines a set of attributes (data) and methods (functions) that objects of that class will have. Classes are user-defined data types.
class Dog:
# Class attribute
species = "Canis familiaris"
def __init__(self, name, age):
# Instance attributes
self.name = name
self.age = age
def bark(self):
return f"{self.name} says Woof!"
Objects (Instances)
An object is an instance of a class. When a class is defined, no memory is allocated until an object of that class is created. Each object has its own unique set of instance attributes.
my_dog = Dog("Buddy", 3) # my_dog is an object (instance) of the Dog class
your_dog = Dog("Lucy", 5) # your_dog is another object
Attributes
Attributes are variables associated with a class or an object. They store data.
- Class Attributes: Belong to the class itself and are shared by all instances of that class (e.g.,
Dog.species
). - Instance Attributes: Belong to individual objects and are unique to each instance (e.g.,
my_dog.name
,my_dog.age
).
print(my_dog.name) # Output: Buddy
print(your_dog.age) # Output: 5
print(Dog.species) # Output: Canis familiaris
print(my_dog.species) # Output: Canis familiaris (accessed via instance)
Methods
Methods are functions defined inside a class that operate on the object's attributes. They define the behavior of an object.
print(my_dog.bark()) # Output: Buddy says Woof!
print(your_dog.bark()) # Output: Lucy says Woof!
Inheritance
Inheritance is a mechanism that allows a new class (subclass or derived class) to inherit properties and behaviors (attributes and methods) from an existing class (superclass or base class). This promotes code reuse.
class Labrador(Dog): # Labrador inherits from Dog
def init(self, name, age, color):
super().init(name, age) # Call the parent's constructor
self.color = color
def retrieve(self):
return f"{self.name} is retrieving the ball."
my_lab = Labrador("Max", 2, "Golden")
print(my_lab.name) # Inherited attribute
print(my_lab.bark()) # Inherited method
print(my_lab.color) # New attribute
print(my_lab.retrieve()) # New method
Polymorphism
Polymorphism means "many forms." In OOP, it refers to the ability of different objects to respond to the same method call in their own specific ways. This often happens through inheritance, where subclasses can override methods of their superclass.
class Cat:
def init(self, name):
self.name = name
def speak(self):
return f"{self.name} says Meow!"
class Duck:
def init(self, name):
self.name = name
def speak(self):
return f"{self.name} says Quack!"
animals = [Dog("Fido", 4), Cat("Whiskers"), Duck("Donald")]
for animal in animals:
# Each animal responds to 'speak()' in its own way
# Dog doesn't have a 'speak' method, so let's modify Dog.bark to speak for demonstration.
# For a proper example, Dog should also have a speak method.
# Let's adjust the Dog class temporarily or assume it has a speak.
# For this example, let's just make sure all objects have a .speak()
pass # Assume Dog also has a .speak() for the purpose of this example.
# print(animal.speak()) # This would call Dog's speak, Cat's speak, Duck's speak
Re-evaluating with common 'speak' method for Dog as well
class DogWithSpeak: # New class to fit polymorphism example
def init(self, name):
self.name = name
def speak(self):
return f"{self.name} says Woof!"
animals_with_speak = [DogWithSpeak("Fido"), Cat("Whiskers"), Duck("Donald")]
for animal in animals_with_speak:
print(animal.speak())
Output:
Fido says Woof!
Whiskers says Meow!
Donald says Quack!
The self
parameter
The self
parameter is a convention in Python (though you can name it differently, it's highly recommended to use self
) that refers to the instance of the class itself. When you define a method in a class, self
is the first parameter, and it automatically receives the calling instance as its argument.
- It allows methods to access and modify the instance's attributes (e.g.,
self.name
). - It's required for instance methods. Class methods and static methods use different conventions (
cls
and no explicit instance parameter, respectively).
class Example:
def init(self, value):
self.instance_value = value # 'self' refers to the instance being created
def display(self):
# 'self' refers to the instance on which display() is called
print(f"Instance value: {self.instance_value}")
obj = Example(10)
obj.display() # Output: Instance value: 10
When obj.display() is called, Python internally passes 'obj' as the 'self' argument.
Object Inspection & Manipulation
dir()
The dir()
function, without arguments, returns a list of names in the current scope. With an argument, it returns a list of valid attributes for the object.
- Parameters:
object
: (Optional) An object to inspect.
- Return Value: A list of strings (attribute names).
- Use Cases: Exploring an object's capabilities, debugging, dynamic programming.
- Usage Examples:
numbers = [1, 2, 3] print(dir(numbers)) # Output: [..., 'append', 'clear', ..., 'sort'] (list of methods and attributes) class MyClass: def init(self): self.a = 10 def method_b(self): pass obj = MyClass() print(dir(obj)) # Output will include 'a' and 'method_b', along with built-in attributes
getattr()
The getattr()
function returns the value of the named attribute of an object. If the named attribute does not exist, it returns a default value if provided, otherwise it raises an AttributeError
.
- Parameters:
object
: The object from which to get the attribute.name
: A string containing the name of the attribute.default
: (Optional) The value to be returned if the named attribute does not exist.
- Return Value: The value of the attribute, or
default
if provided. - Use Cases: Dynamic attribute access, robust error handling for missing attributes.
- Usage Examples:
class Person: def init(self, name, age): self.name = name self.age = age p = Person("Alice", 30) print(getattr(p, "name")) # Output: Alice print(getattr(p, "age")) # Output: 30 print(getattr(p, "city", "Unknown")) # Output: Unknown (with default value) print(getattr(p, "city")) # Raises AttributeError without default
setattr()
The setattr()
function sets the value of the named attribute of an object. If the attribute does not exist, it is created.
- Parameters:
object
: The object on which to set the attribute.name
: A string containing the name of the attribute.value
: The value to be assigned to the attribute.
- Return Value:
None
. - Use Cases: Dynamically adding or changing object attributes.
- Usage Examples:
class Car: def init(self, make): self.make = make my_car = Car("Toyota") print(my_car.make) # Output: Toyota setattr(my_car, "model", "Camry") print(my_car.model) # Output: Camry setattr(my_car, "make", "Honda") # Change existing attribute print(my_car.make) # Output: Honda
hasattr()
The hasattr()
function checks if an object has the specified attribute.
- Parameters:
object
: The object to check.name
: A string containing the name of the attribute.
- Return Value:
True
if the object has the attribute,False
otherwise. - Use Cases: Conditional logic based on an object's capabilities, preventing
AttributeError
. - Usage Examples:
class Book: def init(self, title, author): self.title = title self.author = author my_book = Book("1984", "George Orwell") print(hasattr(my_book, "title")) # Output: True print(hasattr(my_book, "publisher")) # Output: False if hasattr(my_book, "year"): print(my_book.year) else: print("Year attribute not found.") # Output: Year attribute not found.
delattr()
The delattr()
function deletes the specified attribute from an object. If the attribute does not exist, it raises an AttributeError
.
- Parameters:
object
: The object from which to delete the attribute.name
: A string containing the name of the attribute to delete.
- Return Value:
None
. - Use Cases: Dynamically removing attributes from an object.
- Usage Examples:
class Gadget: def init(self, name, price): self.name = name self.price = price my_gadget = Gadget("Smartphone", 999) print(my_gadget.name, my_gadget.price) # Output: Smartphone 999 delattr(my_gadget, "price") print(my_gadget.price) # Raises AttributeError: 'Gadget' object has no attribute 'price' print(delattr(my_gadget, "color")) # Raises AttributeError: 'Gadget' object has no attribute 'color'
Class & Instance Checks
isinstance()
The isinstance()
function checks if an object is an instance of a specified class or a subclass thereof.
- Parameters:
object
: The object to check.classinfo
: A class, type, or a tuple of classes and types.
- Return Value:
True
if the object is an instance,False
otherwise. - Use Cases: Type checking, determining object compatibility with certain operations.
- Usage Examples:
class Vehicle: pass class Car(Vehicle): pass class Bicycle: pass my_car = Car() my_bike = Bicycle() print(isinstance(my_car, Car)) # Output: True print(isinstance(my_car, Vehicle)) # Output: True (Car is a subclass of Vehicle) print(isinstance(my_bike, Car)) # Output: False print(isinstance("hello", str)) # Output: True print(isinstance(123, (int, float)))# Output: True (checks against a tuple of types)
issubclass()
The issubclass()
function checks if one class is a subclass of another class.
- Parameters:
class
: The class to check.classinfo
: A class, type, or a tuple of classes and types.
- Return Value:
True
ifclass
is a subclass ofclassinfo
,False
otherwise. - Use Cases: Determining class hierarchy, ensuring proper inheritance.
- Usage Examples:
class Animal: pass class Mammal(Animal): pass class Dog(Mammal): pass class Reptile(Animal): pass print(issubclass(Dog, Animal)) # Output: True print(issubclass(Mammal, Dog)) # Output: False print(issubclass(Dog, (Mammal, Reptile))) # Output: True (Dog is subclass of Mammal) print(issubclass(Dog, object)) # Output: True (all classes inherit from object) print(issubclass(int, float)) # Output: False
Advanced OOP Utilities
super()
The super()
function provides a way to call a method from a parent or sibling class. It's primarily used in init
methods of subclasses to correctly initialize inherited attributes, and to call overridden methods in the parent class.
- Parameters:
type
: (Optional) The class whose MRO (Method Resolution Order) you want to start from.object_or_type
: (Optional) The instance (for instance methods) or class (for class methods).
- Return Value: A proxy object that delegates method calls to a parent or sibling class.
- Use Cases: Calling parent class constructors and methods, implementing cooperative multiple inheritance.
- Usage Examples:
class Parent: def init(self, name): self.name = name print(f"Parent {self.name} created.") def greet(self): return f"Hello from Parent, {self.name}!" class Child(Parent): def init(self, name, age): super().init(name) # Calls Parent's init self.age = age print(f"Child {self.name} ({self.age}) created.") def greet(self): parent_greeting = super().greet() # Calls Parent's greet method return f"{parent_greeting} I'm also a Child." c = Child("Alice", 5) Output: Parent Alice created. Child Alice (5) created. print(c.greet()) Output: Hello from Parent, Alice! I'm also a Child.
@classmethod
The @classmethod
decorator is used to define a method that belongs to the class itself, rather than to an instance of the class. It receives the class as its first argument (conventionally named cls
), instead of the instance (self
).
- Use Cases: Factory methods (to create instances in alternative ways), methods that operate on class attributes rather than instance attributes.
- Usage Examples:
class MyDate: def init(self, year, month, day): self.year = year self.month = month self.day = day @classmethod def from_string(cls, date_string): # A factory method to create MyDate objects from a string year, month, day = map(int, date_string.split('-')) return cls(year, month, day) # cls refers to MyDate class def display(self): return f"{self.year}-{self.month:02d}-{self.day:02d}" date1 = MyDate(2023, 10, 26) print(date1.display()) # Output: 2023-10-26 date_from_str = MyDate.from_string("2024-01-15") print(date_from_str.display()) # Output: 2024-01-15
@staticmethod
The @staticmethod
decorator is used to define a method that belongs to the class but does not take self
(instance) or cls
(class) as its first argument. It behaves like a regular function but is logically grouped with the class.
- Use Cases: Utility functions that don't need access to instance or class data, but are logically related to the class.
- Usage Examples:
class Calculator: @staticmethod def add(a, b): return a + b @staticmethod def subtract(a, b): return a - b print(Calculator.add(5, 3)) # Output: 8 (called via class) calc = Calculator() print(calc.subtract(10, 4)) # Output: 6 (can also be called via instance, but no 'self' used)
Summary
Key Functions Recap
Throughout this document, we've explored a wide array of Python's built-in functions, each serving a crucial purpose in efficient programming:
- Input/Output & Basic Utilities:
print()
: For displaying output to the console.input()
: For receiving user input as a string.len()
: For getting the length of sequences and collections.type()
: For determining an object's data type.id()
: For getting an object's unique memory address.
- Type Conversion Functions:
int()
,float()
,str()
,bool()
: For converting between basic data types.list()
,tuple()
,set()
,dict()
: For converting iterables to collection types.
- Mathematical & Numeric Functions:
abs()
: For calculating the absolute value.round()
: For rounding numbers to the nearest integer or specified decimal places.min()
,max()
: For finding the smallest or largest item in an iterable or among arguments.sum()
: For summing all numeric items in an iterable.
- Iteration & Sequence Functions:
range()
: For generating sequences of numbers for loops.enumerate()
: For iterating with both index and value.zip()
: For combining elements from multiple iterables.map()
: For applying a function to all items in an iterable.filter()
: For selecting items from an iterable based on a condition.sorted()
: For getting a new sorted list from an iterable.reversed()
: For getting a reverse iterator for a sequence.all()
,any()
: For checking truthiness of all or any elements in an iterable.
- Object-Oriented Programming (OOP) Utilities:
dir()
,getattr()
,setattr()
,hasattr()
,delattr()
: For inspecting and manipulating object attributes.isinstance()
,issubclass()
: For checking object and class relationships.super()
: For calling parent class methods.@classmethod
,@staticmethod
: Decorators for defining class-level and static methods.
Best Practices for Use
- Choose the Right Tool: Understand the purpose of each function and use the most appropriate one for the task to keep your code clean and efficient.
- Read Documentation: When in doubt, consult Python's official documentation for precise parameter usage and behavior, especially for edge cases.
- Handle Exceptions: Be aware of potential errors (e.g.,
ValueError
withint()
on invalid strings,AttributeError
withgetattr()
/delattr()
on non-existent attributes) and usetry-except
blocks where necessary. - Leverage Iterators: Functions like
map()
,filter()
,zip()
, andreversed()
return iterators, which are memory-efficient. Convert them to lists/tuples only when you need to store all results or iterate multiple times. - Readability First: While some built-in functions can lead to very concise code, always prioritize readability. Complex
lambda
functions or nested calls might be better replaced with helper functions for clarity. - Understand Truthiness: Be mindful of Python's "falsy" values (
0
,None
,False
, empty sequences/collections) when using functions likebool()
,all()
,any()
, orfilter()
withNone
as the function.
Further Learning Resources
- Python Official Documentation: The definitive source for all built-in functions: Python Built-in Functions
- Real Python: Excellent tutorials and guides on various Python topics, including built-in functions: Real Python
- W3Schools Python Tutorial: A beginner-friendly resource with many examples: W3Schools Python
- Interactive Python Interpreters: Practice using these functions directly in an interpreter like Jupyter Notebooks or an online Python shell.
Quick Quiz / Revision
Multiple-Choice Questions
-
Which built-in function is used to get input from the user?
print()
get()
input()
read()
-
What will
type([1, 2, 3])
return?<class 'tuple'>
<class 'list'>
<class 'int'>
<class 'dict'>
-
Which function would you use to find the largest number in a sequence
[10, 5, 20, 15]
?min()
greatest()
max()
sum()
-
What is the purpose of the
super()
function in a class?- To define a static method.
- To call a method from a parent class.
- To create a new instance of the current class.
- To check if an object is an instance of a class.
Fill-in-the-Blanks
- The
len()
function returns the ___________ of an object. - To convert the string
"123"
to an integer, you would use the ___________ function. - The
map()
function applies a given function to each item of an ___________ and returns an iterator yielding the results. - When using
enumerate()
, thestart
parameter specifies the index number from which the ___________ is to be started. - The
@staticmethod
decorator defines a method that does not take ___________ or ___________ as its first argument.
Code Snippet Analysis
-
What is the output of the following code?
data = ["apple", "banana", "cherry"] for i, item in enumerate(data, start=1): print(f"{i}. {item}")
Your Answer:
-
What will be the value of
result
?numbers1 = [1, 2, 3] numbers2 = [4, 5, 6] result = list(map(lambda x, y: x * y, numbers1, numbers2))
Your Answer:
-
Explain the output of this code:
class Animal: def speak(self): return "Generic animal sound" class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" animals = [Dog(), Cat(), Animal()] for animal in animals: print(animal.speak())
Your Answer:
-
What is the output of
bool("")
andbool([1, 2])
respectively?print(bool("")) print(bool([1, 2]))
Your Answer:
Short Answer Questions
- Differentiate between 'parameters' and 'arguments' in the context of functions.
- Explain the concept of 'truthiness' in Python with an example.
- When would you use
isinstance()
instead oftype()
for checking an object's type? - Describe a scenario where
zip()
would be a useful function. - What is the main difference between
sorted()
and the.sort()
method of a list?
Common Mistakes and Corrections
1. Not Converting input()
Result to Numeric Types
A frequent error for beginners is forgetting that input()
always returns a string, even if the user enters numbers. Attempting arithmetic operations directly on this string will lead to a TypeError
.
- Incorrect Example:
num_str = input("Enter a number: ") # User inputs '5' total = num_str + 10 print(total)
Why it's a Mistake: Python tries to concatenate the string
'5'
with the integer10
, which is not allowed, resulting in aTypeError
(e.g.,can only concatenate str (not "int") to str
). - Correct Approach: Use
int()
orfloat()
to explicitly convert the input string to the desired numeric type before performing calculations. - Correction:
num_str = input("Enter a number: ") # User inputs '5' num_int = int(num_str) # Convert to integer total = num_int + 10 print(total) # Output: 15 For floats: price_str = input("Enter a price: ") # User inputs '19.99' price_float = float(price_str) # Convert to float discounted_price = price_float * 0.9 print(f"{discounted_price:.2f}") # Output: 17.99
2. Misunderstanding range()
's Exclusive Stop Value
The range()
function's stop
parameter specifies an upper bound that is not included in the generated sequence, leading to "off-by-one" errors if not accounted for.
- Incorrect Example:
# Goal: print numbers 1 to 5 for i in range(1, 5): print(i)
Why it's a Mistake:
range(1, 5)
generates numbers from 1 up to (but not including) 5, so it will print 1, 2, 3, 4. The number 5 is excluded. - Correct Approach: Increase the
stop
value by one to include the desired upper limit. - Correction:
# Correct way to print numbers 1 to 5 for i in range(1, 6): # 'stop' value is 6 to include 5 print(i) Output: 1 2 3 4 5
3. Not Converting Iterator Objects (map
, filter
, zip
, reversed
) for Direct Display or Multiple Iterations
Functions like map()
, filter()
, zip()
, and reversed()
return iterator objects. These objects produce values on demand and can typically be iterated over only once. Printing them directly won't show their contents, and trying to iterate over them multiple times will often yield an empty sequence after the first use.
- Incorrect Example:
numbers = [1, 2, 3] squared_iterator = map(lambda x: xx, numbers) print(squared_iterator) # Expected: [1, 4, 9] for num in squared_iterator: # This will work once print(num) for num in squared_iterator: # This will be empty print(num)
Why it's a Mistake: Printing
squared_iterator
directly shows its memory address (e.g.,) instead of the calculated values. After the first loop, the iterator is exhausted, so the second loop produces nothing.
- Correct Approach: Convert the iterator to a list (or tuple) if you need to display all its contents at once, store them, or iterate over them multiple times.
- Correction:
numbers = [1, 2, 3] squared_list = list(map(lambda x: xx, numbers)) # Convert to list print(squared_list) # Output: [1, 4, 9] Now you can iterate multiple times for num in squared_list: print(num, end=" ") # Output: 1 4 9 print() for num in squared_list: print(num, end=" ") # Output: 1 4 9 print() Alternatively, just iterate once if conversion is not needed: for item in map(lambda x: x * 2, numbers): print(item) # Output: 2, 4, 6
4. Using type()
for Inheritance-Aware Type Checking Instead of isinstance()
While type()
gives the exact type of an object, it doesn't account for inheritance. If you need to check if an object is an instance of a class or any of its subclasses, isinstance()
is the correct tool.
- Incorrect Example:
class Animal: pass class Dog(Animal): pass my_dog = Dog() print(type(my_dog) == Animal) # Expected: True (because Dog is an Animal)
Why it's a Mistake:
type(my_dog)
returns<class 'main.Dog'>
. Comparing this toAnimal
(which is<class 'main.Animal'>
) using==
will result inFalse
, even though aDog
is anAnimal
. This can lead to incorrect conditional logic. - Correct Approach: Use
isinstance()
, which correctly handles class hierarchies. - Correction:
class Animal: pass class Dog(Animal): pass my_dog = Dog() print(isinstance(my_dog, Animal)) # Output: True my_animal = Animal() print(isinstance(my_animal, Dog)) # Output: False (an Animal is not necessarily a Dog)
5. Misinterpreting round()
's Tie-Breaking Rule
In Python 3, round()
uses "round half to even" (also known as "bankers' rounding"). This means if a number is exactly halfway between two integers, it rounds to the nearest even integer. Many expect it to always round up (e.g., 2.5
to 3
).
- Incorrect Example:
print(round(2.5)) # Expected: 3 print(round(3.5)) # Expected: 4
Why it's a Mistake: Python 3's
round(2.5)
will return2
(nearest even integer), andround(3.5)
will return4
(nearest even integer). This can cause subtle bugs in financial or statistical calculations if not understood. - Correct Approach: Be aware of the "round half to even" rule. If you need a different rounding behavior (e.g., always round up or down, or round half up), you might need to implement it manually or use the
decimal
module. - Correction:
print(round(2.5)) # Output: 2 print(round(3.5)) # Output: 4 print(round(4.5)) # Output: 4 (nearest even) print(round(5.5)) # Output: 6 (nearest even) If you specifically need "round half up": import math print(math.floor(2.5 + 0.5)) # Output: 3 (general way to simulate round half up for positive numbers) print(math.floor(3.5 + 0.5)) # Output: 4
6. Attempting to get len()
of a non-sequence/collection type
The len()
function is designed for objects that have a measurable length, like strings, lists, tuples, dictionaries, and sets. It will raise a TypeError
if used on objects that don't define a length, such as integers or floats.
- Incorrect Example:
number = 12345 length = len(number) print(length)
Why it's a Mistake: An integer itself does not have a "length" in Python's terms. It's a single atomic value. This will raise a
TypeError: object of type 'int' has no len()
. - Correct Approach: If you need the number of digits in a number, convert it to a string first.
- Correction:
number = 12345 length = len(str(number)) # Convert number to string, then get its length print(length) # Output: 5 float_num = 3.14159 float_length = len(str(float_num)) print(float_length) # Output: 7 (counts digits and the decimal point)
Frequently Asked Questions (FAQ)
Q: Are all built-in functions always available?
A: Yes, Python's built-in functions are always available without needing to import any modules. They are part of the global namespace when Python starts.
Q: Can I create my own functions with the same name as a built-in function?
A: Yes, you can. Python allows you to define a function with the same name as a built-in one. However, this is generally considered bad practice as it will "shadow" or override the built-in function, meaning you will lose access to the original built-in function in that scope. It can lead to confusion and unexpected behavior.
Q: What is the difference between a built-in function and a method?
A: A built-in function is a standalone function that is globally available and doesn't "belong" to any specific object (e.g., len()
, print()
). A method, on the other hand, is a function that belongs to an object (or class) and is called on that object (e.g., my_list.append()
, my_string.upper()
). Methods operate on the data specific to their object.
Q: How can I find out what a built-in function does?
A: You can use the built-in help()
function or access the doc
attribute. For example, help(len)
or print(len.doc)
will display the documentation string for the len()
function, explaining its purpose and usage.
Q: Why do some built-in functions return an "iterator" or "object at memory address" instead of a list?
A: Functions like map()
, filter()
, zip()
, and reversed()
return iterator objects for efficiency. Iterators generate values one at a time as they are requested, rather than creating an entire list in memory all at once. This is particularly useful for very large sequences where creating a full list would consume excessive memory. If you need a list or tuple of all items, you can explicitly convert the iterator (e.g., list(map_object)
).
Q: Is it better to use built-in functions or write my own custom logic?
A: Generally, it's always better to use built-in functions when they fit your needs. Built-in functions are:
- Optimized: Often implemented in C, making them much faster than equivalent Python code.
- Reliable: Thoroughly tested and maintained by the Python core developers.
- Readable: Using standard functions makes your code more understandable to other Python developers.
- Concise: They reduce boilerplate code.
However, if a built-in function doesn't exactly match your requirements, writing custom logic or functions is necessary.