Sequences and Iterables

Learn about sequences and iterables in Python. Fundamental concepts for working with collections of data.

Ali Berro

By Ali Berro

8 min read Section 6
From: Python Fundamentals: From Zero to Hero

Sequences and Iterables

Python provides many ways to work with collections of data. Understanding what sequences and iterables are, and how they differ, is crucial for effective Python programming. These concepts form the foundation for working with multiple items at once.

What are Sequences?

A sequence in Python is an ordered collection of items where each item has a specific position (index). The order is deterministic, meaning the same sequence will always have the same order. Sequences are a fundamental data type in Python and are used extensively in loops.

Types of Sequences

Python has seven built-in sequence types:

  1. Strings (str) - Ordered collection of characters
  2. Lists (list) - Ordered, mutable collection of items
  3. Tuples (tuple) - Ordered, immutable collection of items
  4. Range objects (range) - Immutable sequence of numbers
  5. Bytes (bytes) - Immutable sequence of bytes
  6. Bytearrays (bytearray) - Mutable sequence of bytes
  7. Buffers - Low-level sequence interface

Tip

We’ve already seen strings and will learn more about them along with lists and tuples in later sections. The range() function we covered earlier is also a sequence type!

Characteristics of Sequences

All sequences share these key characteristics:

  • Ordered: Items have a specific position (index starting from 0)
  • Indexable: Access items by their position using [index]
  • Sliceable: Extract portions using slicing [start:end]
  • Length: Get the number of items using len()
  • Iterable: Can be processed item by item

What are Iterables?

An iterable is any object that contains or can produce a series of items that can be accessed one at a time. It’s a broader concept than sequences. All sequences are iterables, but not all iterables are sequences.

Key Difference

  • Sequences: Have a specific order, are indexable, and have a length
  • Iterables: Can produce items one by one, but may not have indexing or a specific order

Examples of Iterables

  • Sequences (which are also iterables): strings, lists, tuples, range objects
  • Non-sequence iterables: sets, dictionaries, files, generators

The key point is that iterables make it possible to work with collections of items. Sequences are a special type of iterable that provide extra features such as indexing and slicing.

Common Sequence Operations

Sequences support many common operations. Including:

  • Membership Testing (in and not in)
  • Length (len())
  • Minimum and Maximum (min() and max())
  • Counting (count())
  • Searching (index())
  • Indexing ([i])
  • Slicing ([i:j] and [i:j:k])
  • Concatenation (+)
  • Repetition (*)

1. Membership Testing (in and not in)

Check if an item exists in a sequence:

text = "Python"
print("P" in text) # True
print("x" in text) # False
print("x" not in text) # True
numbers = range(1, 6)
print(3 in numbers) # True
print(10 in numbers) # False

2. Length (len())

Get the number of items in a sequence:

text = "Hello"
print(len(text)) # 5
numbers = range(1, 6)
print(len(numbers)) # 5

3. Minimum and Maximum (min() and max())

Find the smallest and largest items:

numbers = range(5, 10)
print(min(numbers)) # 5
print(max(numbers)) # 9
text = "hello"
print(min(text)) # 'e' (alphabetically first)
print(max(text)) # 'o' (alphabetically last)

4. Counting (count())

Count how many times an item appears:

text = "hello"
print(text.count("l")) # 2
numbers = range(1, 6)
print(numbers.count(2)) # 1

5. Searching (index())

Find the position of an item (returns the first occurrence):

text = "hello"
print(text.index("e")) # 1

6. Indexing ([i])

Indexing allows access to individual items in a sequence by their position. It’s similar to finding a specific item in a numbered list.

How Indexing Works

Each item in a sequence has a position number called an index. Python uses zero-based indexing, which means:

  • The first item is at index 0 (not 1)
  • The second item is at index 1
  • The third item is at index 2
  • And so on…

Here’s a visual example with the string "Python":

Index: 0 1 2 3 4 5
String: P y t h o n

To access an item, square brackets [] are used with the index number:

text = "Python"
print(text[0]) # 'P' (first character at index 0)
print(text[1]) # 'y' (second character at index 1)
print(text[2]) # 't' (third character at index 2)
print(text[5]) # 'n' (sixth character at index 5)

Note

Some programming languages (like Lua) use 1-based indexing, where the first item is at index 1.

Negative Indexing

Negative indexing counts from the end of the sequence:

  • -1 is the last item
  • -2 is the second-to-last item
  • -3 is the third-to-last item
  • And so on…

Here’s the same string with negative indices:

Negative Index: -6 -5 -4 -3 -2 -1
Index: 0 1 2 3 4 5
String: P y t h o n

Negative indexing is useful when the length of a sequence is not known but items need to be accessed from the end:

text = "Python"
print(text[-1]) # 'n' (last character)
print(text[-2]) # 'o' (second-to-last character)
print(text[-6]) # 'P' (first character, same as text[0])
numbers = range(10, 41, 10)
print(numbers[0]) # 10 (first item)
print(numbers[3]) # 40 (last item, at index 3)
print(numbers[-1]) # 40 (last item, using negative index)
print(numbers[-2]) # 30 (second-to-last item)

If an index that doesn’t exist is used (like text[10] for a 6-character string), Python will raise an IndexError. Make sure the index is within the valid range: from 0 to len(sequence) - 1 for positive indices, or from -len(sequence) to -1 for negative indices.

7. Slicing ([i:j] and [i:j:k])

Slicing allows extraction of a portion (or “slice”) of a sequence. Instead of getting one item like indexing, slicing gives a new sequence containing multiple items.

Basic Slicing Syntax

The basic slicing syntax is [start:end]:

  • start: The index where the slice begins (this item is included)
  • end: The index where the slice ends (this item is excluded)

The end index is exclusive, meaning the item at the end index is NOT included in the slice.

Let’s see this with the string "Python":

Index: 0 1 2 3 4 5
String: P y t h o n
text = "Python"
# Get characters from index 0 to 2 (excluding 3)
print(text[0:3]) # "Pyt"
# Includes: P (index 0), y (index 1), t (index 2)
# Excludes: h (index 3)
# Get characters from index 2 to the end
print(text[2:]) # "thon"
# When end is omitted, it goes to the end of the sequence
# Includes: t, h, o, n (indices 2, 3, 4, 5)
# Get characters from the start to index 3 (excluding 4)
print(text[:4]) # "Pyth"
# When start is omitted, it starts from the beginning
# Includes: P, y, t, h (indices 0, 1, 2, 3)
# Excludes: o (index 4)
# Get the entire sequence
print(text[:]) # "Python"
# When both start and end are omitted, you get everything

Slicing with Step

Step can be added to skip items: [start:end:step]

  • start: Beginning index (inclusive, defaults to 0)
  • end: Ending index (exclusive, defaults to end)
  • step: How many items to skip between each item (defaults to 1)
text = "Python"
# Get every character (step = 1, which is the default)
print(text[::1]) # "Python"
# Get every 2nd character (step = 2)
print(text[::2]) # "Pto"
# Includes: P (index 0), t (index 2), o (index 4)
# Skips: y, h, n
# Get characters from index 1 to 5, every 2nd one
print(text[1:5:2]) # "yh"
# Starts at index 1 (y), ends before index 5
# Includes: y (index 1), h (index 3)
# Skips: t (index 2), o (index 4)

Reversing a Sequence

When a negative step (like -1) is used, the sequence can be reversed:

text = "Python"
print(text[::-1]) # "nohtyP" (reversed)
# The negative step makes it go backwards
print(text[4:2:-1]) # "oh"
# Reverse a portion
print(text[2:5][::-1]) # "oht" (slice first, then reverse)
numbers = range(0, 6)
# Get items from index 1 to 3 (excluding 4)
print(numbers[1:4]) # 1, 2, 3
# Get every 2nd item
print(numbers[::2]) # 0, 2, 4
# Includes: 0 (index 0), 2 (index 2), 4 (index 4)
# Get items from index 1 to the end, every 2nd one
print(numbers[1::2]) # 1, 3, 5
# Reverse the list
print(numbers[::-1]) # 5, 4, 3, 2, 1, 0

8. Concatenation (+)

Combine two sequences of the same type:

text1 = "Hello"
text2 = "World"
print(text1 + " " + text2) # "Hello World"

9. Repetition (*)

Repeat a sequence multiple times:

text = "Hi"
print(text * 3) # "HiHiHi"
print(3 * text) # "HiHiHi" (same result)

Non-Sequence Types

Not all iterable types are sequences. Some collections don’t maintain order or support indexing. Two important examples are:

  • Sets are unordered collections of unique items. They are iterable (you can access each item), but they don’t have a specific order and don’t support indexing:
  • Dictionaries store key-value pairs. They maintain insertion order (Python 3.7+), but you access items by key, not by numeric index:

Note

Both sets and dictionaries will be covered in the next chapter.

Course Progress

Section 15 of 17

Back to Course