In Python, you cannot access values inside a set using indexing syntax. A set is an unordered collection of unique elements. Because a set is unordered, they do not record element position or insertion order. Therefore sets do not support indexing, slicing or other sequence-like behaviour.

Indexing syntax is suitable for iterable objects such as strings or lists.

If you attempt to index or slice a set, you will raise the “TypeError: ‘set’ object is not subscriptable”.

You can convert the set to a list using the built-in list() method to solve this error.

This tutorial will go through the error in detail and how to solve it with code examples.


TypeError: ‘set’ object is not subscriptable

Let’s break up the error message to understand what the error means. TypeError occurs whenever you attempt to use an illegal operation for a specific data type. The part set object tells us the error concerns an illegal operation for floating-point numbers.

The part “is not subscriptable” tells us we cannot access an element of the object in question.

Subscriptable objects contain a collection of objects, and we access these objects by indexing.

You cannot retrieve a specific value from a set using indexing. A Python set is an unordered collection of unique elements, therefore, does not maintain element position or order of insertion.

Example: Trying to Index a Set Instead of a List

Let’s look at an example where we have a set of integers; we want to get the last element of the set using the indexing operator. The code is as follows:

numbers = {2, 4, 6, 7, 8}

print(f'The last number in the set is: {numbers[-1]}')

The index value -1 gets the last element in a collection.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-3a97ae86710b> in <module>
      1 numbers = {2, 4, 6, 7, 8}
      2 
----> 3 print(f'The last number in the set is: {numbers[-1]}')

TypeError: 'set' object is not subscriptable

We get the TypeError because we are trying to access the elements of a set using indexing. Set objects do not support indexing, slicing or any other sequence-like behaviour.

Solution

To solve this error, we can convert the list to a set using the built-in list() function and then access the list’s last element using indexing.

# Define set

numbers = {2, 4, 6, 7, 8}

# Convert set to list

numbers_list = list(numbers)

# Converted list

print(numbers_list)

# Confirming type is list

print(type(numbers_list))

# Last element in list

print(f'The last number in the list is: {numbers_list[-1]}')

Let’s run the code to get the result:

[2, 4, 6, 7, 8]
<class 'list'>
The last number in the list is: 8

Example: Indexing a Set Instead of a Dictionary

Another common source of this error is incorrectly creating a set instead of a dictionary then trying to access the set using indexing. Let’s look at an example.

We will write a program that allows users to buy items from a shop for a fantasy quest. First, we will define the shop, which will store the item names and prices:

shop = {"sword",25, "shield", 10, "armor", 40, "helmet", 20, "amulet", 50}

Then, we will define a variable called inventory and assign an empty list to it. This list will store the items the user buys from the shop. We will also define a variable called gold and assign an integer value of 100 to it. This value is the amount the user has to spend in the shop.

inventory = []

gold = 100

Next, we will define a function that takes the item the user wants to buy and the amount of gold the user has as parameters. If the amount of gold is greater or equal to the item’s price, we append the item to the inventory and then deduct the cost from the starting amount of gold. If the amount of gold is less than the item’s price, we will print that the user does not have enough gold to buy the item.

def buy(item, gold):
    if gold >= shop[item]:
        print(f'You have bought: {item}')
        inventory.append(item)
        gold -= shop[item]
        print(f'You have {gold} gold remaining')
    else:
        print(f'Sorry you do need {shop[item]} gold to buy: {item}')

Now we have the program, and we can ask the user what item they want to buy using the input() function and then call the buy() function.

item = input("What item would you like to buy for your quest?: ")

buy(item, gold)

Let’s run the code to see what happens:

What item would you like to buy for your quest?: sword

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-644e6440f655> in <module>
     15 item = input("What item would you like to buy for your quest?: ")
     16 
---> 17 buy(item, gold)

<ipython-input-6-644e6440f655> in buy(item, gold)
      6 
      7 def buy(item, gold):
----> 8     if gold >= shop[item]:
      9         print(f'You have bought: {item}')
     10         inventory.append(item)

TypeError: 'set' object is not subscriptable

We get the TypeError because the shop variable is a set, not a dictionary. We define a dictionary with key-value pairs with a colon between the key and the value of each pair. We use commas to separate key-value pairs, not keys from values. When we try to get the cost of an item using indexing, we are trying to index a set, and sets do not support indexing.

Solution

We need to define a dictionary using colons to solve this error. Let’s look at the revised code:

shop = {"sword":25, "shield":10, "armor":40, "helmet":20, "amulet":50}

inventory = []

gold = 100

def buy(item, gold):
    if gold >= shop[item]:
        print(f'You have bought: {item}')
        inventory.append(item)
        gold -= shop[item]
        print(f'You have {gold} gold remaining')
    else:
        print(f'Sorry you do need {shop[item]} gold to buy: {item}')

item = input("What item would you like to buy for your quest?: ")

buy(item, gold)

Let’s run the code to get the result:

What item would you like to buy for your quest?: sword
You have bought: sword
You have 75 gold remaining

We successfully bought a sword for our fantasy quest and have 75 gold remaining.

Summary

Congratulations on reading to the end of this tutorial! The TypeError: ‘set’ object is not subscriptable occurs when you try to access elements of a set using indexing or slicing. You may encounter this when you incorrectly define a set instead of a dictionary. To create a dictionary, ensure you put a colon between the key and value in each pair and separate each pair with a comma.

If you want to access an element of a set using indexing, convert the set to a list using the list() method.

To learn more about Python for data science and machine learning, go to the online courses page on Python for the most comprehensive courses available.

Have fun and happy researching!