Converting Between Collections

Concepts covered: Dictionaries

Each collection type doubles as a function. list(x) takes any collection and builds a new one of the named type holding the same items, and tuple(x) and set(x) work the same way. The source is untouched. What differs is which guarantees the new collection makes, and that is where values keep or lose something on the way across.

What survives the trip

From and toKeepsLoses
list to tupleorder, every duplicatethe ability to edit
tuple to listorder, every duplicatethe fixed guarantee
list to setone copy of each distinct valueorder, duplicates, slot numbers
set to listthe distinct values, now in slotsnothing further; the order is the set's
dict to listthe keys, in insertion orderthe values
dict to setthe distinct keysthe values and the order

Read each row as a promise. A conversion to a tuple or a list keeps every item in its slot, so the length never changes. A set keeps one copy of each distinct value and throws away the slots, so the length can only shrink or stay the same. When a dict is the source, only its keys make the trip and the values stay behind.

readings = [4, 2, 4, 9, 2]
as_tuple = tuple(readings)
as_set = set(readings)
print(as_tuple, len(as_tuple))
print(as_set, len(as_set))
print(readings)

Output:

(4, 2, 4, 9, 2) 5
{9, 2, 4} 3
[4, 2, 4, 9, 2]

All 5 readings went in. The tuple reports 5 with the order intact. The set reports 3 and prints {9, 2, 4}, which is the slot order inside the set and has no relation to the order the readings arrived. The last line shows readings still holds all 5.

readings = [4, 2, 4, 9, 2]

as_set = set(readings)
back_to_list = list(as_set)
locked = tuple(readings)

print("original:", readings)
print("as set:", as_set)
print("back:", back_to_list)
print("locked:", locked)
print("same length:", len(readings) == len(back_to_list))
original: [4, 2, 4, 9, 2]
as set: {9, 2, 4}
back: [9, 2, 4]
locked: (4, 2, 4, 9, 2)
same length: False

Watch back_to_list appear: it is a real list with a slot 0, and back_to_list[0] would work. What it cannot give back is the original arrival order or the 2 lost duplicates, because the set never had them.

A dict converts to its keys

Handing a dict to list() or set() gives you the keys only, in insertion order for the list. The values stay behind in the dict. This is the usual way to get a dict's keys into something you can index.

inventory = {"bolt": 120, "nut": 300, "washer": 45}
names = list(inventory)
print(names)
print(names[1])
print(len(set(inventory)))

Output:

['bolt', 'nut', 'washer']
nut
3

Building a dict from pairs

dict() runs the other direction. Give it a list of 2-item tuples and each tuple's first item becomes a key, with its second item as that key's value.

pairs = [("north", 12), ("south", 30)]
regions = dict(pairs)
print(regions)
print(regions["south"])

Output:

{'north': 12, 'south': 30}
30

Conversion never edits the source, so to drop duplicates and keep working with a list, assign the result back: readings = list(set(readings)). After that line the order is the set's order, and the duplicate count is gone for good.

Practice

Both exercises hinge on what set() throws away and what list() can and can't restore.

What does this program print?

tags = ["red", "blue", "red", "green", "blue"]
unique = set(tags)
tags = list(unique)
print(len(tags), len(unique))

Converting a dict to a set never shrinks it, because its keys were unique to begin with, so len(set(inventory)) always equals len(inventory). Converting it to a list is what makes reading by position possible: square brackets on the dict look up a key, while square brackets on the list read a slot.

ExpressionResult
`inventory["nut"]`300
`inventory[0]`stops with `KeyError: 0`
`list(inventory)[0]``'bolt'`
`len(set(inventory))`3

About this lesson

This section is part of the Data Structures: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.