TypeError: '<' not supported between instances of 'str' and 'int'
Exception: TypeErrorCategory: runtime (comparison)Raised at: the <, >, <= or >= that compared a string with a number
What this error means
You compared a string with a number using an ordering operator. Python 3 refuses to guess which one is bigger, so it raises TypeError.
Traceback (most recent call last):
File "demo.py", line 2, in <module>
if score > 50:
TypeError: '>' not supported between instances of 'str' and 'int'
The operator in the message tells you which comparison failed, and the two type names tell you which side was which. Read it as: *the > operator does not work between a str on the left and an int on the right.*
'a' > 5 # ๐ฅ '>' not supported between 'str' and 'int'
5 > 'a' # ๐ฅ '>' not supported between 'int' and 'str'
'a' < 'b' # โ
str to str is fine โ lexicographic
5 < 9 # โ
int to int is fine
'a' == 5 # โ
equality always works, and is always False
'a' != 5 # โ
same
Note the last two: equality comparisons never raise. Only the ordering operators โ <, >, <=, >= โ do, because there is no sensible ordering between different types. That asymmetry is why this bug can sit unnoticed for a long time.
Where the string comes from
In almost every real case the string is there because something returned text when a number was expected. Three sources dominate:
# 1 โ input() always returns a string
age = input("Age: ") # '25', not 25
if age > 18: # ๐ฅ
if int(age) > 18: # โ
convert at the point of entry
# 2 โ CSV and dict values are strings
row = {"score": "91"} # read from a CSV
if row["score"] > 50: # ๐ฅ
if int(row["score"]) > 50: # โ
# 3 โ command-line arguments
import sys
n = sys.argv[1] # always a string
if n > 10: # ๐ฅ
# 4 โ environment variables
import os
timeout = os.environ.get("TIMEOUT", "30") # string, even the default
if timeout > 5: # ๐ฅ
The fix is always the same and always in the same place: convert at the boundary, where the data enters your program, not at every point of use. Then the rest of the code can assume the type is right.
The sorting case that hides it
This is the version that confuses people, because the traceback points at sorted() or .sort() rather than at your comparison:
Traceback (most recent call last):
File "demo.py", line 3, in <module>
rows.sort(key=lambda r: r["age"])
TypeError: '<' not supported between instances of 'str' and 'int'
rows = [
{"name": "Asha", "age": 30},
{"name": "Ravi", "age": "25"}, # โ one string among the ints
]
rows.sort(key=lambda r: r["age"]) # ๐ฅ when it compares 30 with '25'
# find the bad rows before sorting
bad = [r for r in rows if not isinstance(r["age"], int)]
print(bad) # [{'name': 'Ravi', 'age': '25'}]
# or coerce in the key
rows.sort(key=lambda r: int(r["age"])) # โ
The reason the traceback is unhelpful: sorting compares adjacent items internally, so the failing comparison happens inside C code, far from the line that loaded the data. Print the types before sorting โ [type(r['age']) for r in rows] finds the odd one out in one line.
A related trap: sorting a list containing None. None cannot be ordered against anything, so mixed-in None values produce the same class of error with NoneType in the message instead.
Why Python 2 allowed this
If you are porting old code or reading old answers, you may see this comparison *work*. Python 2 permitted ordering between unrelated types using an arbitrary but consistent rule based on type names:
# Python 2 โ did not raise, but the answer was meaningless
'a' > 5 # True, because 'str' sorts after 'int' by name
# Python 3 โ raises, which is the correct behaviour
'a' > 5 # TypeError
Python 2's behaviour was a bug, not a feature: the result depended on type names, not on values, so it was never the answer anyone wanted. Python 3 raising an error is what surfaces the real mistake โ that a string got where a number belonged.
Fixing it properly
# convert once, at the boundary
def read_age(raw):
return int(str(raw).strip())
age = read_age(input("Age: "))
if age > 18:
...
# when the input may be invalid
try:
age = int(raw)
except ValueError:
age = 0 # or raise, or skip the row โ but decide deliberately
# when comparing text that looks numeric, be explicit
if float(row["score"]) > 50:
...
# when you genuinely want lexicographic order
if str(a) < str(b):
... # '10' < '9' โ probably not what you meant
That last one is the trap in reverse. Converting both sides to str silences the error but gives you dictionary ordering, where '10' < '9' because '1' < '9'. If you are comparing numbers, convert to numbers.
Related messages worth knowing
- TypeError: can only concatenate str (not "int") to str โ the + operator version of the same string/number mix-up.
- ValueError: invalid literal for int() with base 10 โ what you get when the conversion itself fails.
- TypeError: the parent guide โ the whole family of wrong-type operations.
๐ฎ๐ณ Hindi เคฎเฅเค เคธเคฎเคเฅเค
TypeError: '<' not supported between instances of 'str' and 'int' tab aata hai jab aap string aur number ko ordering operator (<, >, <=, >=) se compare karte ho. Python 3 andaza lagane se inkaar kar deta hai ki kaun bada hai, isliye error deta hai. Ek important baat: equality (==, !=) kabhi error nahi deta โ 'a' == 5 chupchaap False deta hai. Sirf ordering operators fail hote hain, kyunki alag types ke beech koi sensible order nahi hota. Isi wajah se ye bug der tak chhupa reh sakta hai. String aata kahaan se hai? Char jagah: input() hamesha string deta hai; CSV aur dict ki values string hoti hain; sys.argv ke arguments string hote hain; aur os.environ se mila value bhi string hota hai. Fix hamesha ek hi hai aur hamesha ek hi jagah: boundary par convert karo, jahaan data program me aata hai โ har use par nahi. Sabse confusing case sorting hai: rows.sort(key=...) par error aata hai aur traceback aapke comparison ko nahi, sort() ko point karta hai, kyunki comparison C code ke andar hota hai. Ek string value poore int list me ghusi ho to yahi hota hai. [type(r['age']) for r in rows] print karke odd one out turant mil jaata hai. Aur dono taraf str() me badalna error chhupa deta hai par dictionary order de deta hai โ '10' < '9' hoga, jo shayad aap chahte nahi the.
TypeError Hindi เคฎเฅเค เค เฅเค เคเคฐเคจเคพ เคธเฅเคเฅเค โ