This chapter introduces Python’s built-in sequence collections—lists and tuples—and focuses on how and when to use each. Lists are mutable and suited to sequences of similar items, while tuples are immutable and often used as lightweight records holding different kinds of data. Both are sequences, so they support iteration, membership tests, indexing, and slicing (with strings as the third sequence type). The discussion emphasizes practical selection between the two, noting that lists offer rich methods for modification and reordering, whereas tuples excel as fixed, structured containers.
A central theme is writing generic, type-agnostic code by exploiting the common sequence protocol. The chapter contrasts single-element indexing (which returns whatever is stored) with slicing (which always returns the same sequence type), enabling solutions that preserve input types. This idea powers an exercise that returns the first and last elements using slices, and another that reimplements a flexible summation via a variadic function that works for numbers, strings, lists, and tuples. Along the way, it reinforces Python’s dynamic typing and truthiness rules for empty sequences, shows how slices avoid index errors and enable concise sub-sequence processing, and highlights tools like range, list comprehensions, and function-passing idioms.
The chapter then applies these ideas to everyday tasks: sorting a list of dictionaries by a specific field with the key parameter to sorted, using either small inline functions or operator.itemgetter (including multi-key sorts); counting repeated letters in words with collections.Counter and selecting winners via max with a key function; and formatting tuple-based records into aligned, human-friendly columns with str.format and argument unpacking. It also briefly explains why Python lists aren’t fixed-size arrays, how they grow under the hood, and encourages readable, reusable solutions that compose core sequence operations with standard-library helpers.
Individual elements (from the Python Tutor)
Retrieving slices from a list (from the Python Tutor)
Retrieving slices from a tuple (from the Python Tutor)
Naive, incorrect adding of slices (from the Python Tutor)
Working solution (from the Python Tutor)
After assigning the first element to output (from the Python Tutor)
After adding elements to output (from the Python Tutor)
Summary
In this chapter, we explored a number of ways we can use lists and tuples and manipulate them within our Python programs. It’s hard to exaggerate just how common lists and tuples are, and how familiar you should be with them. To summarize, here are some of the most important points to remember about them:
Lists are mutable and tuples are immutable, but the real difference between them is how they’re used: lists are for sequences of the same type, and tuples are for records that contain different types.
You can use the built-in sorted function to sort either lists or tuples. You’ll get a list back from your call to sorted.
You can modify the sort order by passing a function to the key parameter. This function will be invoked once for each element in the sequence, and the output from the function will be used in ordering the elements.
If you want to count the number of items contained in a sequence, try using the Counter class from the collections module. It not only lets us count things quickly and easily, and provides us with a most_common method, but also inherits from dict, giving us all of the dict functionality we know and love.
FAQ
What’s the difference between lists and tuples, and when should I use each?Lists are ordered and mutable; tuples are ordered and immutable. In practice, use lists for sequences of similar items (e.g., many users or IPs) and tuples for fixed “records” of different fields (e.g., name, birth date). A list of tuples is common when you have many records.What sequence operations work the same on strings, lists, and tuples?They are all sequences, so you can iterate with for, test membership with in, index with square brackets (s[0], s[-1]), and slice (s[a:b], s[-n:]).Why does the firstlast function use slices (s[:1] and s[-1:]) instead of indexes?Slices always return the same sequence type as the input, so s[:1] and s[-1:] preserve type and can be concatenated with + to form a two-element sequence of the original type. Indexing returns the element itself (which might be a different type), making + behave incorrectly.What happens if I go out of bounds with indexes or slices?Indexing out of range (s[5]) raises IndexError. Slices are forgiving: s[3:100] returns the available tail without error.How can I write a mysum that works for numbers, strings, lists, and tuples?Accept any number of arguments with *items. If none, return the empty tuple items. Otherwise set output = items[0] and loop over items[1:], doing output += item each time. All arguments must be the same type and support +.How do I sort a list of dicts by a specific key (e.g., country name)?Use sorted with the key parameter: sorted(countries, key=operator.itemgetter('name')). You can also use key=lambda d: d['name']. itemgetter supports multiple keys, e.g., itemgetter('size', 'name').What does operator.itemgetter do, and why is it useful?itemgetter returns a function that fetches items via square-bracket access. For example, final = itemgetter(-1) gets the last element of any sequence; itemgetter(2, 4) returns a function that extracts a tuple of elements at indexes 2 and 4. It’s handy for key functions in sorting.How can I find the word with the most repeated letters in a list of words?Use collections.Counter to count letters in each word and most_common(1)[0][1] to get that word’s highest letter count. Then pick the word with max(words, key=that_count_function). Ties can return any highest-scoring word.How can I neatly format and align columns from a list of tuples?Sort tuples with sorted(list_of_tuples, key=operator.itemgetter(0)). Build lines with a format template like '{0:15} {1:10,} {2:15,}'. Unpack each tuple with *country and join lines with '\n'. The , specifier adds thousands separators.Are Python lists arrays, and how do they grow in memory?Lists aren’t fixed-size typed arrays; they’re dynamic arrays of pointers. Python over-allocates space so appends are often amortized cheap, but occasional resizes occur. You can observe growth steps with sys.getsizeof. For true arrays, see the array module or NumPy, but most Python code uses lists/tuples.
pro $24.99 per month
access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!