––– Day 2 –––
––– Sequence –––
It’s easy to get sequence and iterable confused as they can seem quite similar at first. But they're not
A sequence is an iterable which you can index using an integer inside square brackets, such as `some_sequence[0]`
I've confused these two terms so much in the early days until I properly took some time to learn what's what
By the way, if you want to refresh your memory on "iterable" here's yesterday's first thread in the series:
twitter.com/s_gruppetta_ct/status/1625544155786285057
Lists, tuples, and strings are common types which are sequences
You can do the following with all of them:
>>> numbers = [2, 4, 6, 8]
>>> numbers[1]
4
>>> name = "Stephen"
>>> name[4]
'h'
>>> more_numbers = (5, 10, 15, 20)
>>> more_numbers[-1]
20
A sequence also always has a length
This means you can use the built-in function `len()` to get the number of items in a sequence:
>>> len(numbers)
4
>>> len(name)
7
>>> len(more_numbers)
4
The term _sequence_ refers to objects which can be indexed using integers
Therefore, even though dictionaries have a length and can be indexed using square brackets, they’re not sequences since you can use any valid key inside the square brackets and not just integers
All sequences are iterables
But not all iterables are sequences
We'll see more about this later in the series, too
You’ve already seen that a dictionary is not a sequence even though it’s an iterable
Let’s look at some other iterables which are not sequences
First up: sets
You can start by confirming that sets _are_ iterable:
>>> unique_numbers = {3, 5, 9, 12, 5}
>>> unique_numbers
{9, 3, 12, 5}
>>> for item in unique_numbers:
... print(item)
...
9
3
12
5
>>> iter(unique_numbers)
<set_iterator object at 0x1154b4740>
Either using `unique_numbers` in a `for` loop or making sure no error is raised when you use it as an argument in `iter()` is sufficient to show that the set `unique_numbers` is iterable
But a set is not a sequence:
>>> len(unique_numbers)
4
>>> unique_numbers[0]
Traceback (most recent call last):
...
TypeError: 'set' object is not subscriptable
Although you _can_ get the length of a set using `len()`, you cannot index it
The error states that a set is not subscriptable (which basically means you cannot index it)
Here’s another example:
>>> points = zip(["Stephen", "Kate"], [10, 20])
>>> len(points)
Traceback (most recent call last):
...
TypeError: object of type 'zip' has no len()
>>> points[0]
Traceback (most recent call last):
...
TypeError: 'zip' object is not subscriptable
The object returned by `zip()` doesn’t have a length and cannot be indexed either. Therefore, it’s not a sequence
However, it is an iterable:
>>> for item in points:
... print(item)
...
('Stephen', 10)
('Kate', 20)
We’ll talk about zip objects in a later post
A class will create a sequence if:
• it has both `__len__()` and `__getitem__()` defined as special methods, and
• `__getitem__()`, which makes the object indexable, can only take an integer argument
––– Etymology Corner –––
The term “sequence” comes from the Latin verb 'sequi' which means “to follow”
Each item in a sequence follows the other one. That’s why you can use integer indices!