, ,

List, Tuple, or Set? Choosing the Right Container (Python for Beginners, Part 7)

Lists, tuples and sets are Python three everyday containers. See what each one does, when to reach for which, and how to strip duplicates the clean way while the expense tracker learns to remember every entry.

Python for Beginners · Part 7 of 20

One variable holds one thing. A shopping trip is not one thing. It is bread and milk and eggs and ten more items, and you do not want ten variables named item1 through item10. Python has a container built for exactly this, and it is the one you will reach for every single day.

items.py
items = ['bread', 'milk', 'eggs']
print(items)
print(len(items), 'items')
output
['bread', 'milk', 'eggs']
3 items

That is a list. One name, many values, kept in order. This part covers the list and its two quieter cousins, the tuple and the set, and where each one earns its place.

The short versionA list holds many items in order and you can change it freely, written with square brackets. A tuple is a list you have promised not to change, written with round brackets. A set keeps only unique items and has no order, written with curly brackets. Reach for a list by default, a tuple when a group should stay fixed, and a set when duplicates have to go.

All you need is Python 3 and about thirty five minutes. This part sits on top of the loops from Part 6, because a list and a for loop are made for each other. Nothing here touches files or paths, so the code runs the same on Windows, macOS and Linux. Copy any block, run it, and your screen should match. One warning first. If you copy code off a web page and Python complains about a SyntaxError near a quote, your straight quotes may have turned curly on the way over. Type the quotes yourself and it clears up. Career switchers, this is the part where your programs stop handling one value and start handling real batches of data.

Four containers, one quick map

Before any code, here is the whole chapter on one screen. Python gives you four everyday containers. You will spend most of your time in the first one, but knowing when the others fit saves real effort later.

ContainerBracketsIn orderDuplicatesChange laterReach for it when
list[ ]yesallowedyesalmost anything, the default
tuple( )yesallowednoa fixed group that stays put
set{ }noremovedadd or remove onlyunique items, fast checks
dict{ key: value }yeskeys uniqueyeslabelled pairs, see Part 8

The dictionary is next in Part 8, so this part spends its time on the first three. Keep one detail from that last row in mind now, because it trips up everyone once. An empty pair of curly brackets {} makes a dictionary, not a set. For an empty set you write set().

The list: your default container

A list is an ordered run of values inside square brackets, separated by commas. The values can be numbers, strings, or a mix. Order is kept, so the first thing you put in is the first thing you get back.

Reading items by position

Each item sits at a numbered position called its index, and counting starts at 0, not 1. That zero is the single most important fact about lists, so it is worth saying plainly. The first item is at index 0. A negative index counts from the end, so -1 is the last item. A slice with a colon pulls out a range.

read.py
fruits = ['apple', 'banana', 'cherry']
print(fruits[0])
print(fruits[-1])
print(fruits[1:3])
output
apple
cherry
['banana', 'cherry']

The slice fruits[1:3] starts at index 1 and stops before index 3, the same left out end you met with range in Part 6. So it gives you positions 1 and 2, and not 3.

items = [‘bread’, ‘milk’, ‘eggs’, ‘jam’] 0 1 2 3 bread milk eggs jam -4 -3 -2 -1 red numbers count from the front, grey numbers count from the back

The same four items carry two sets of positions. items[0] and items[-4] are both bread.

Changing a list in place

Lists are made to be edited. append adds to the end, sort reorders in place, in tests membership, and len counts. A few of them together:

grow.py
nums = [3, 1, 2]
nums.append(4)
nums.sort()
print(nums)
print(len(nums))
print(2 in nums)
output
[1, 2, 3, 4]
4
True

Notice the list itself changed. append and sort did not hand back a new list, they rearranged the one you already had. That in place habit is the root of the one gotcha every beginner meets with lists.

Gotcha: two names, one listCopying a list is not as simple as it looks. When you write b = a, you do not get a second list. You get a second name pointing at the very same list, so a change through one shows up through the other.
alias.py
a = [1, 2, 3]
b = a
a.append(4)
print(b)
output
[1, 2, 3, 4]
You never touched b, yet it grew, because b and a are the same list under two names. When you want a real, separate copy, ask for one with b = a.copy() or b = a[:]. Then edits to one leave the other alone.

The tuple: a list you promise not to change

A tuple is an ordered group of values, like a list, but frozen. Once you make it, you cannot add, remove, or replace items. You write it with round brackets.

point.py
point = (3, 4)
print(point[0])
x, y = point
print(x, y)
output
3
3 4

Reading a tuple works exactly like a list, with the same index positions. The last line is a small trick called unpacking. It hands the two values in point straight into x and y in one line. Try point[0] = 5 and Python stops you with a TypeError that says a tuple does not support item assignment, which is the whole point of a tuple.

The one comma that matters

There is a trap with a single item tuple. Brackets alone do not make a tuple, the comma does.

comma.py
one = (5,)
not_a_tuple = (5)
print(type(one))
print(type(not_a_tuple))
output
<class 'tuple'>
<class 'int'>

Without the trailing comma, (5) is just the number 5 with some brackets around it. The comma in (5,) is what tells Python you meant a one item tuple. For two or more values the comma is already there, so this only bites on single item tuples.

Here is a plain opinion, since beginners often ask when tuples matter. Most days, they do not. Use a list and move on. Reach for a tuple in two honest cases: when a small group of values belongs together and must not be edited by accident, like a pair of coordinates or a fixed row, and later, when you need something that can act as a dictionary key, which a list cannot. If neither is true, a tuple is just a list you cannot fix when requirements change. Do not sprinkle them everywhere for the feeling of safety.

The set: unique items, fast checks

A set holds only unique items and does not keep them in any order. Put a duplicate in and it simply collapses to one. That single behaviour makes sets the cleanest way to strip repeats and the fastest way to ask does this contain X.

colors.py
colors = {'red', 'blue', 'red'}
print(len(colors))
print('red' in colors)
output
2
True

Three values went in, two came out, because the second red was a duplicate. One warning about sets. They have no order, so printing a set may show its items in any arrangement, and you cannot ask for colors[0]. There is no position 0 to fetch. If you need order or positions, use a list.

The most common real use is removing duplicates from a list in a single line. Wrap the list in set() and the repeats vanish.

dedup.py
names = ['ana', 'bob', 'ana']
unique = set(names)
print(len(unique))
output
2
list with repeats apple apple pear apple set(…) set, each once apple pear

Four items with three apples go in. The set keeps one apple and one pear.

A worked example: cleaning a guest list

Here is a small job you might actually be handed. Someone gives you a guest list where a few people were entered twice, and they want to know how many real people are coming. Build it up the way you would for real.

guests.py
guests = ['Ana', 'Bob', 'Ana', 'Cara', 'Bob']
unique = set(guests)
print('Invited entries:', len(guests))
print('Real people:', len(unique))
output
Invited entries: 5
Real people: 3

Five entries, three people. Now say you try to print the first unique guest by position, out of habit:

guests.py
print(unique[0])
terminal
Traceback (most recent call last):
  File 'guests.py', line 5, in <module>
    print(unique[0])
TypeError: 'set' object is not subscriptable

Read the last line first, the habit from Part 6. It says a set is not subscriptable, which is the formal way of saying you cannot index it with [0]. That is expected, not a mistake in your logic. A set has no positions. If you want them back in order, and you want the first copy of each name kept, there is one clean move:

guests.py
ordered = list(dict.fromkeys(guests))
print(ordered)
output
['Ana', 'Bob', 'Cara']

dict.fromkeys walks the list once, keeps the first time it sees each name, and drops later repeats, and because dictionaries remember insertion order in Python 3, the result stays in the original order. Wrap it in list() and you have a deduplicated list that a set alone could not give you.

Project step: the tracker remembers every entryPart 6 kept only a running total, so the tracker knew the sum but forgot each expense the moment it added it. A list fixes that. Store every amount in a list with append, then count and total it at the end. Everything here is a list plus the loop and input from earlier parts.
expenses.py
print('My Expense Tracker')
amounts = []
while True:
    category = input('Category or done: ')
    if category == 'done':
        break
    amount = float(input('Amount: '))
    amounts.append(amount)
    print('Saved', amount, 'for', category)
print('Entries:', len(amounts))
print('Total spent:', sum(amounts))
terminal
My Expense Tracker
Category or done: Groceries
Amount: 250
Saved 250.0 for Groceries
Category or done: Bus
Amount: 40
Saved 40.0 for Bus
Category or done: done
Entries: 2
Total spent: 290.0
sum(amounts) adds every number in the list in one call, and len(amounts) counts them, so the total is no longer a variable you nurse by hand. Each expense now survives until the program ends. Part 8 pairs each amount with its category using a dictionary, so an entry stops being a bare number and becomes a labelled record.
Real interview questionA teammate writes newest = old_list.append(‘x’) and is baffled that newest prints as None instead of the new list. What happened? The strong answer is quick: append changes the list in place and returns None, so there is nothing useful to catch. The new item is sitting in old_list, not in a returned value. The rule to carry away is that list methods which modify in place, like append, sort and reverse, return None. Keep using the original variable, do not assign their result to a new one.
On the jobEvery batch of data you meet at work is a list underneath. Rows from a spreadsheet, records from a database, results from an API, files in a folder. You loop over the list to handle each item, use a set to catch duplicates or check membership without a slow scan, and pull out a tuple when a few values belong together and should not be edited. The first time you clean a messy export with one set() call instead of scrolling through it by eye, the tool has paid for the time you spent learning it.
Try it yourselfYou are given prices = [40, 15, 40, 90, 15]. Print the highest price, and how many different prices there are. Use what you just learned about max, set and len. Match this output.
expected output
Highest: 90
Different prices: 3
Show solution
prices.py
prices = [40, 15, 40, 90, 15]
print('Highest:', max(prices))
print('Different prices:', len(set(prices)))
output
Highest: 90
Different prices: 3

max scans the list for the biggest number, and set(prices) collapses the two 40s and two 15s so len counts three distinct values.

Questions that come up with collections

When should I use a tuple instead of a list? Use a tuple when the group should not change, like a fixed pair of coordinates or a record you do not want edited by accident. If you will add or remove items, use a list.

Why did my second variable change when I only changed the first? Because b = a makes two names for one list, not a copy. Change one and both see it. Make a real copy with b = a.copy() when you want them independent.

How do I remove duplicates from a list? Wrap it in set(), as in unique = set(my_list). If you also need the original order kept, use list(dict.fromkeys(my_list)), which keeps the first copy of each.

Why can I not do my_set[0]? A set has no order and no positions, so indexing makes no sense and Python raises a TypeError. Loop over the set, or turn it into a list first with list(my_set).

What is the comma in (5,) for? Without it, (5) is just the number 5 in brackets. The comma is what makes it a one item tuple. For two or more values, like (5, 6), the comma is already there.

You can now build a list, read items by position including from the end, slice a range out of it, grow and sort it with append and sort, protect a fixed group inside a tuple, and strip duplicates or test membership fast with a set.

Part 8 gives each expense a label instead of a bare number by pairing a key with a value in a dictionary, the container that finally lets one entry hold an amount, a category and a note together. Keep expenses.py exactly as it stands, because Part 8 builds on this list. Try the prices task before you open the solution.

Python for Beginners · Part 7 of 20
« Previous: Part 6  |  Complete Guide  |  Next: Part 8

References

Python docs: data structures, lists and sets
Python docs: tuples
Python docs: dict.fromkeys

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading