These are the fundamental constructs around which you build your programs. Each data structure provides a particular way of organising data so it can be accessed efficiently, depending on your use case. Python ships with an extensive set of data structures in its standard library.
Python programming language has four collection data types- list, tuple, sets and dictionary. But python also comes with a built-in module known as collections which has specialised data structures which basically covers for the shortcomings of the four data types.
Strings are a form of collection and is treated for the most part like a tuple of characters.
An iterable in Python is anything you can loop over using a for loop. It contains multiple values that you can access one by one. An object is iterable if it can be passed to the iter() function.
numbers = [1, 2, 3]
iterator = iter(numbers) # Converts to an iterator
print(next(iterator)) # Outputs: 1
print(next(iterator)) # Outputs: 2
print(next(iterator)) # Outputs: 3
If an object works with iter(), it's an iterable.
Here are some common iterables in Python:
Lists
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print(num) # Outputs: 1, 2, 3, 4, 5
Strings (Because you can loop over characters)
word = "hello"
for letter in word:
print(letter) # Outputs: h, e, l, l, o
Tuples
fruits = ("apple", "banana", "cherry")
for fruit in fruits:
print(fruit) # Outputs: apple, banana, cherry
Dictionaries (Iterates over keys by default)
person = {"name": "Alice", "age": 25}
for key in person:
print(key, "->", person[key])
Output:
name -> Alice
age -> 25
Sets
unique_numbers = {10, 20, 30}
for num in unique_numbers:
print(num)
Range (Special Iterable for Loops)
for i in range(5): # 0 to 4
print(i)
An object is iterable if it can be passed to the iter() function.
numbers = [1, 2, 3]
iterator = iter(numbers) # Converts to an iterator
print(next(iterator)) # Outputs: 1
print(next(iterator)) # Outputs: 2
print(next(iterator)) # Outputs: 3
If an object works with iter(), it's an iterable.
An iterator is an object that allows you to go through (iterate over) elements one at a time. It remembers where it left off and returns the next item when you ask for it.
numbers = [1, 2, 3] # A list (iterable)
iterator = iter(numbers) # Convert to an iterator
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
# print(next(iterator)) # This would cause an error (StopIteration)
Explanation:
iter(numbers) turns the list into an iterator.
next(iterator) gives the next item and moves forward.
Once there are no more items, calling next() gives a StopIteration error.
You can make your own iterator using a class. It needs:
A __iter__() method → Returns the iterator itself.
A __next__() method → Returns the next value.
Example: Custom Counter Iterator
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self # The object itself is the iterator
def __next__(self):
if self.current >= self.end:
raise StopIteration # Stops iteration
value = self.current
self.current += 1
return value
# Using the iterator
counter = Counter(1, 5)
for num in counter:
print(num)
Output:
1
2
3
4
✅ When working with large data (so you don’t load everything into memory).
✅ When reading files line by line (open(file).readlines() is an iterator).
✅ When creating infinite sequences (e.g., Fibonacci generator).
Every variable in python holds an instance of an object. There are two types of objects in python i.e. Mutable and Immutable objects. Whenever an object is instantiated, it is assigned a unique object id. The type of the object is defined at the runtime and it can’t be changed afterwards. However, it’s state can be changed if it is a mutable object.
To summarise the difference, mutable objects can change their state or contents and immutable objects can’t change their state or content.
These are of in-built types like int, float, bool, string, unicode, tuple. In simple words, an immutable object can’t be changed after it is created.