Python errors / TypeError

TypeError in Python

A value was used in a way its type doesn't allow, like adding text to a number or calling something that isn't a function.

TypeError: can only concatenate str (not "int") to str

Check these first

  1. Check the types. print(type(x)) shows what a value really is: "5" is text, 5 is a number.
  2. Convert first. int("5"), float("2.5") and str(5) give you the type you need. input() always gives text.
  3. Look for None. A function without a return, or a method like .sort(), gives back None.

Causes and fixes

1 Adding text and a number

Python won't guess whether you mean maths or joining text. Turn the number into text with str(), or write an f-string: f"Age: {age}".

Broken
age = 20
print("Age: " + age)
TypeError: can only concatenate str (not "int") to str
Fixed
age = 20
print("Age: " + str(age))
Age: 20

2 Comparing text with a number

input() gives back text, even when someone types a number. Convert it with int() or float() before comparing it or doing maths with it.

Broken
age = "20"  # typed text, as input gives back
if age >= 18:
    print("Adult")
TypeError: '>=' not supported between instances of 'str' and 'int'
Fixed
age = int("20")
if age >= 18:
    print("Adult")
Adult

3 The wrong number of arguments

A call has to give a value for each parameter the function's def lists, in the same order.

Broken
def greet(name, greeting):
    print(greeting, name)

greet("Ada")
TypeError: greet() missing 1 required positional argument: 'greeting'
Fixed
def greet(name, greeting):
    print(greeting, name)

greet("Ada", "Hello")
Hello Ada

4 None where a value was expected

.sort() sorts the list itself and gives back None, as does any function without a return. Use sorted() for a sorted copy, or use the list after sorting it.

Broken
nums = [3, 1, 2]
sorted_nums = nums.sort()
print(sorted_nums[0])
TypeError: 'NoneType' object is not subscriptable
Fixed
nums = [3, 1, 2]
sorted_nums = sorted(nums)
print(sorted_nums[0])
1

5 Looping over a number

A for loop goes over a list, a string or a range. To repeat something a number of times, loop over range(count).

Broken
count = 3
for i in count:
    print(i)
TypeError: 'int' object is not iterable
Fixed
count = 3
for i in range(count):
    print(i)
0
1
2

6 A variable named like a function

Naming a variable sum, list, str, max or input hides Python's function of that name. Give the variable another name, such as total.

Broken
sum = 0
for n in [1, 2, 3]:
    sum += n
print(sum([4, 5]))
TypeError: 'int' object is not callable
Fixed
total = 0
for n in [1, 2, 3]:
    total += n
print(sum([4, 5]))
9

Other messages

More messages TypeError can show. Open yours for what it means and how to fix it.

'str' object does not support item assignment

Text can't be changed in place. Build a new string instead, from the pieces you want.

Broken
word = "cat"
word[0] = "b"
print(word)
TypeError: 'str' object does not support item assignment
Fixed
word = "cat"
word = "b" + word[1:]
print(word)
bat
unhashable type: 'list'

Dictionary keys and set items have to be values that can't change, such as numbers, text and tuples, not lists. Use a tuple instead.

Broken
seen = {[1, 2]: "pair"}
print(seen)
TypeError: unhashable type: 'list'
Fixed
seen = {(1, 2): "pair"}
print(seen)
{(1, 2): 'pair'}
list indices must be integers or slices, not str

A list's positions are whole numbers. A position typed in, like an input() answer, is text: convert it with int().

Broken
nums = [10, 20]
position = "0"
print(nums[position])
TypeError: list indices must be integers or slices, not str
Fixed
nums = [10, 20]
position = "0"
print(nums[int(position)])
10
string indices must be integers

The value is text, not the dictionary or list you expected. Print it to see what it holds, and check where it came from.

Broken
person = "Ada"
print(person["name"])
TypeError: string indices must be integers, not 'str'
Fixed
person = {"name": "Ada"}
print(person["name"])
Ada
'int' object is not subscriptable

[ ] reads an item of a list, a string or a dictionary; a number has no items. For a number's digits, turn it into text first.

Broken
year = 2024
print(year[0])
TypeError: 'int' object is not subscriptable
Fixed
year = 2024
print(str(year)[0])
2
object of type 'int' has no len()

len() counts the items of a list, a string or a dictionary; a number has none. To count a number's digits, use len(str(n)).

Broken
n = 12345
print(len(n))
TypeError: object of type 'int' has no len()
Fixed
n = 12345
print(len(str(n)))
5
can't multiply sequence by non-int

Text and lists can only be repeated a whole number of times, like "ab" * 3. For maths, turn the text into a number first.

Broken
price = "2.5"
print(price * 1.5)
TypeError: can't multiply sequence by non-int of type 'float'
Fixed
price = "2.5"
print(float(price) * 1.5)
3.75
'str' object cannot be interpreted as an integer

range() needs a whole number, not text. Convert with int(), as with anything input() gives back.

Broken
count = "3"
for i in range(count):
    print(i)
TypeError: 'str' object cannot be interpreted as an integer
Fixed
count = "3"
for i in range(int(count)):
    print(i)
0
1
2
Dog() takes no arguments

The class has no __init__ to take them, usually because it's misspelled: __init__ has two underscores on each side.

Broken
class Dog:
    def _init_(self, name):
        self.name = name

rex = Dog("Rex")
print(rex.name)
TypeError: Dog() takes no arguments
Fixed
class Dog:
    def __init__(self, name):
        self.name = name

rex = Dog("Rex")
print(rex.name)
Rex
not all arguments converted during string formatting

On text, % fills in a template, so "7" % 2 isn't a remainder: the number is still text, as input() gives it. Convert it first: int(n) % 2.

Broken
n = "7"  # typed text, as input gives back
if n % 2 == 1:
    print("odd")
TypeError: not all arguments converted during string formatting
Fixed
n = "7"  # typed text, as input gives back
if int(n) % 2 == 1:
    print("odd")
odd
argument of type 'int' is not iterable

in looks inside a list, a string or a dictionary. To look for a digit in a number, make it text first.

Broken
year = 1975
print(7 in year)
TypeError: argument of type 'int' is not iterable
Fixed
year = 1975
print("7" in str(year))
True
sequence item 0: expected str instance, int found

join() joins text only. Turn each number into text first.

Broken
nums = [1, 2, 3]
print(", ".join(nums))
TypeError: sequence item 0: expected str instance, int found
Fixed
nums = [1, 2, 3]
print(", ".join(str(n) for n in nums))
1, 2, 3
'module' object is not callable

import datetime gives you the module, and what you call is inside it, with the same name. Import that instead, or write both names: datetime.datetime(...). The same goes for random.random().

Broken
import datetime
day = datetime(2024, 12, 25)
print(day.year)
TypeError: 'module' object is not callable. Did you mean: 'datetime.datetime(...)'?
Fixed
from datetime import datetime
day = datetime(2024, 12, 25)
print(day.year)
2024
greet() got an unexpected keyword argument 'nme'

A name=value in a call has to use a name from the function's def, spelled the same.

Broken
def greet(name):
    print("Hi", name)

greet(nme="Ada")
TypeError: greet() got an unexpected keyword argument 'nme'
Fixed
def greet(name):
    print("Hi", name)

greet(name="Ada")
Hi Ada
'set' object is not subscriptable

A set has no order, so it has no positions, and nor do a dictionary's .keys() and .values(). Loop over it, or make a list first: sorted(colors) or list(scores.keys()).

Broken
colors = {"red", "green"}
print(colors[0])
TypeError: 'set' object is not subscriptable
Fixed
colors = {"red", "green"}
print(sorted(colors)[0])
green
int() argument must be a string, a bytes-like object or a real number, not 'list'

int() turns one value into a number. For a list of them, convert each item.

Broken
parts = "3 4 5".split()
print(int(parts))
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'list'
Fixed
parts = "3 4 5".split()
print([int(p) for p in parts])
[3, 4, 5]
must be real number, not str

math's functions need a number, and text that looks like one isn't. Convert it with float() first.

Broken
import math
side = "16"  # typed text, as input gives back
print(math.sqrt(side))
TypeError: must be real number, not str
Fixed
import math
side = "16"  # typed text, as input gives back
print(math.sqrt(float(side)))
4.0
list.append() takes exactly one argument (2 given)

append() adds one item. To add several, extend() with a list of them.

Broken
nums = [1, 2]
nums.append(3, 4)
print(nums)
TypeError: list.append() takes exactly one argument (2 given)
Fixed
nums = [1, 2]
nums.extend([3, 4])
print(nums)
[1, 2, 3, 4]

Still stuck?