How to Solve ‘Tuple’ Object Does Not Support Item Assignment (Python)

🏷️

This is about TypeError: ‘Tuple’ Object Does Not Support Item Assignment in Python.

You’ll learn:

  • The specifics of the tuple data type
  • The difference between immutable and mutable data types
  • How to change immutable data types
  • Lots more

So if you want to understand this error in Python and how to solve it, then you’re in the right place.

Let’s jump right in!

Mutable, or Immutable? That Is the Question

Data types in Python are mutable or immutable.

All data types that are numeric, for example, are immutable

You can write something like this:

a = 1
a
1

And:

a = a + 1
a
2

Have you changed the variable a

Not really: When you write a = 1, you put the object 1 in memory and told the name a to refer to this literal. 

Next, when you write a = a + 1, Python evaluates the expression on the right:

Python takes the object referred by a (the 1) and then adds 1 to it. 

You get a new object, a 2. This object goes right into the memory and a references instead of object 1

The value of object 1 has not changed—it would be weird if 1 would out of a sudden a 2, for example, wouldn’t it? So instead of overwriting an object (1), a new object (2) is created and assigned to the variable (a).

Mutable Data Types

More complex data types in Python are sequences such as: 

  • Strings
  • Tuples
  • Bytes
  • Lists
  • Byte Arrays

Sequences contain several values, which can be accessed by index.

However, some sequences are mutable (byte arrays, lists), while others are immutable (tuples)

You can create a tuple and access its elements like this:

tup1 = (1, "two", [3])
tup1[1]
two

Yet if you try to change one of the elements, you get an error:

tup1[1] = '2'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-903ae2cb95b0> in <module>()
----> 1 tup1[1] = '2'

TypeError: 'tuple' object does not support item assignment

Notice that the item in the tuple at index 2 is a list. You can change the list without changing the tuple:

tup1[2].append(4)
tup1
(1, 'two', [3, 4])

The object stored in the tuple remains the same, but its contents have changed. But what if you still need to change the element in the tuple?

You can do this by converting the tuple to a list. Then you change the element, and then convert the list to a tuple again:

tup1 = list(tup1)
tup1[0] = 'uno'
tup1 = tuple(tup1)
tup1
('uno', 'two', [3, 4])

For large amounts of data, conversion operations can take quite a long time:

import random
import time

tup2 = tuple(random.random() for _ in range(100_000_000))

t = time.process_time()
tup2 = list(tup2)
elapsed_time = time.process_time() - t
print('tuple->list: ', elapsed_time)

tup2[0] = random.random()

t = time.process_time()
tup2 = tuple(tup2)
elapsed_time = time.process_time() - t
print('list->tuple: ', elapsed_time)
tuple->list:  0.8301777420000036
list->tuple:  0.9393838999999957

As you can see, for a list of 100 million float numbers, this operation takes about a second. This is not a long time for most tasks, but it is still worth considering if you are dealing with large amounts of data.

However, there is another way to “change” a tuple element—you can rebuild a tuple using slicing and concatenation:

tup1 = (1, "two", [3])
tup1 = ('uno',) + tup1[1:]
tup1

Note that it is necessary to put a comma in parentheses to create a tuple of one element. If you use just parentheses, then (‘uno’) is not a tuple, but a string in parentheses

Concatenating a string with a tuple is not possible:

tup1 = ('uno') + tup1[1:]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-c51d4ed19b5a> in <module>()
----> 1 tup1 = ('uno') + tup1[1:]

TypeError: must be str, not tuple

Interestingly, you can use shorthand operators on a tuple, like this:

tup = (1, 2)
tup += (3, 4, 5)
tup
(1, 2, 3, 4, 5)

Or even like this:

tup = (1, 2)
tup *= 3
tup
(1, 2, 1, 2, 1, 2)

3 Examples of TypeError: ‘Tuple’ Object Does Not Support Item Assignment in Python

Let’s look at some practical examples of when this error can occur. The simplest is when you initially enter the sequence incorrectly:

list1 = (1, 2, 3)
list1[0] = 'one'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-da9ebc4ef661> in <module>()
      1 list1 = (1, 2, 3)
----> 2 list1[0] = 'one'

TypeError: 'tuple' object does not support item assignment

In this example, the name list1 refers to a tuple despite the list in the name. The name does not affect the type of variable. To fix this error, simply change the parentheses to square brackets in the constructor:

list1 = [1, 2, 3]
list1[0] = 'one'
list1
['one', 2, 3]

Perhaps you have a list with some values, such as the student’s name and grade point average:

grades = [('Alice', 98), ('Bob', 65), ('Carol', 87)]

Alice did a poor job this semester, and her GPA dropped to 90:

grades[0][1] = 90
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-dc371b5fb12e> in <module>()
----> 1 grades[0][1] = 90

TypeError: 'tuple' object does not support item assignment

Unfortunately, you cannot just change the average score in such a list. You already know that you can convert a tuple to a list, or form a new tuple. For example, like this:

grades[0] = (grades[0][0], 90)
grades
[('Alice', 90), ('Bob', 65), ('Carol', 87)]

However, if you need to change values regularly, it makes sense to switch from a list of tuples to a dictionary. Dictionaries are a perfect fit for such tasks. You can do this easily with the dict() constructor:

grades = [('Alice', 98), ('Bob', 65), ('Carol', 87)]
grades = dict(grades)
grades
{'Alice': 98, 'Bob': 65, 'Carol': 87}

Now you can change the average by student name:

grades['Alice'] = 90
grades
{'Alice': 90, 'Bob': 65, 'Carol': 87}

#1 Real World Example of TypeError: ‘Tuple’ Object Does Not Support Item Assignment in Python

An interesting example of a novice programmer trying to enter values in a list from the keyboard using the eval() function:

def my_sort(list):
  for index in range(1, len(list)):
    value = list[index]
    i = index-1
    while i>=0:
      if value <list[i]:
        list[i +1] = list[i]
        list[i] = value
        i = i-1
      else:
        break
  return
 
input_list = eval(input("Enter list items:"))
my_sort (input_list)
print(input_list)
Enter list items:3, 2, 4, 1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-16-a1ba042b65c4> in <module>()
     13 
     14 input_list = eval(input("Enter list items:"))
---> 15 my_sort (input_list)
     16 print(input_list)

<ipython-input-16-a1ba042b65c4> in my_sort(list)
      5     while i>=0:
      6       if value <list[i]:
----> 7         list[i +1] = list[i]
      8         list[i] = value
      9         i = i-1

TypeError: 'tuple' object does not support item assignment

This method is not very reliable by itself.

Even if the user enters the correct sequence separated by commas—for example, 3, 2, 4, 1—it will be evaluated in a tuple. 

Naturally, an attempt to assign a new value to a tuple element in the line list[i +1] = list[i] raises a TypeError: ‘tuple’ object does not support item assignment

Here, you see another mistake—which, by the way, may even be invisible during program execution. 

The my_sort function uses the list data type name as the argument name. This is not only the name of the data type, but also the list constructor. 

Python will not throw an error while executing this code, but if you try to create a list using the constructor inside the my_sort function, you will have big problems.

In this case, to enter elements into the list, it would be more correct to read the entire string and then split it using the split() method. If you need integer values, you can also apply the map() function, then convert the resulting map object into a list:

input_list = list (map(int, input("Enter the list items: ") .split ()))
input_list
Enter the list items: 4 2 3 1
[4, 2, 3, 1]

The construction looks a little cumbersome, but it does its job. You can also enter list items through a list comprehension:

input_list = [int (x) for x in input("Enter the list items: ") .split ()]
input_list
Enter the list items: 4 2 3 1
[4, 2, 3, 1]

You can choose the design that you like best.

#2 Real World Example of TypeError: ‘Tuple’ Object Does Not Support Item Assignment in Python

Another example of when a TypeError: ‘tuple’ object does not support item assignment may occur is the use of various libraries. 

If you have not studied the documentation well enough, you may not always clearly understand which data type will be returned in a given situation. In this example, the author tries to make the picture redder by adding 20 to the red color component:

from PIL import Image
image = Image.open('balloon.jpg')
pixels = list (image.getdata ())
for pixel in pixels: 
    pixel[0] = pixel[0] + 20    
image.putdata(pixels)
image.save('new.bmp')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-2e305d7cf9e6> in <module>()
      3 pixels = list (image.getdata ())
      4 for pixel in pixels:
----> 5     pixel[0] = pixel[0] + 20
      6 image.putdata(pixels)
      7 image.save('new.bmp')

TypeError: 'tuple' object does not support item assignment

This produces an error on the line pixel[0] = pixel[0] + 20. How?

You are converting pixels to a list in line of code 3. Indeed, if you check the type of the pixels variable, you get a list:

type(pixels)
list

However, in the loop, you iterate over the pixels list elements, and they already have a different type. Check the type of the pixels list element with index 0:

type(pixels[0])
tuple

And this is a tuple!

So, you can solve this problem by converting lists to tuples inside a loop, for example.

However, in this case, you will need to slightly adjust the iterable value. This is because you will need the pixel color values and the index to write the new values into the original array. 

For this, use the enumerate() function:

for i, pixel in enumerate(pixels): 
    pixel = list (pixel)
    pixel [0] = pixel [0] + 20
    pixels [i] = tuple (pixel)

The program will work successfully with that version of a loop, and you will get a redder image at the output. It would be more correct to trim values above 255, for example:

pixel[0] = min(pixel [0] + 20, 255)

But if the program consists only of this transformation, then Python will already truncate the values when saving the image.

Here’s more Python support:

More Similar Articles

Leave a Comment

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

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed

Menu