Django-Admin.ru

ValueError в Python: что значит и как исправить

Что значит ValueError в Python и как исправить invalid literal for int(), could not convert string to float, unpack, math domain error и ошибки pandas.

Редакция Django-Admin.ru
· 17 мин чтения

Содержание · 16 разделов
  1. Частые сообщения ValueError: таблица
  2. Что означает ValueError
  3. invalid literal for int() with base 10
  4. Пустая строка: invalid literal for int() with base 10: ”
  5. Дробное число в int()
  6. Несколько чисел в одной строке
  7. could not convert string to float
  8. too many values to unpack и not enough values to unpack
  9. math domain error
  10. list.remove(x): x not in list
  11. substring not found
  12. time data does not match format
  13. max() iterable argument is empty
  14. NumPy и pandas: truth value is ambiguous
  15. ValueError и TypeError: в чём разница
  16. Как обработать ValueError: проверка или try/except
  17. Как вызвать ValueError в своём коде
  18. Частые вопросы
  19. Почему int(input()) выдаёт invalid literal for int() with base 10: ”?
  20. Как узнать, какое именно значение вызвало ValueError?
  21. Перехватывает ли except ValueError ошибки JSON и кодировки?
  22. Что значит ValueError: Field ‘id’ expected a number but got ‘abc’ в Django?
  23. Почему текст ошибки отличается от того, что пишут в интернете?
  24. Как перевести строку с запятой в число?
  25. Итог

ValueError в Python означает, что функция получила аргумент подходящего типа, но с недопустимым значением. Классический пример — int("abc"): функция int() принимает строки, но строку "abc" нельзя превратить в целое число. Чтобы исправить ошибку, посмотрите на последнюю строку traceback: в ней есть и функция, и значение, которое ей не понравилось. Дальше либо очистите и проверьте данные до вызова, либо перехватите ошибку через try/except ValueError.

age = int("abc")
ValueError: invalid literal for int() with base 10: 'abc'

Ниже — частые сообщения ValueError с причинами и исправлениями, разница с TypeError, проверка пользовательского ввода и правила, по которым стоит выбрасывать ValueError в своём коде. Примеры проверены на Python 3.12 и 3.14, NumPy 2.5 и pandas 3.0.

Частые сообщения ValueError: таблица

СообщениеПримерЧто исправить
invalid literal for int() with base 10: '...'int("3.5"), int("")Пустая строка, дробь, запятая, лишние символы
could not convert string to float: '...'float("12,5")Запятая вместо точки, пробелы-разделители, пустота
too many values to unpack (expected 2)a, b = [1, 2, 3]Слева меньше переменных, чем значений справа
not enough values to unpack (expected 2, got 1)a, b = "x".split()Справа меньше значений; часто — цикл по словарю
math domain errormath.sqrt(-1), math.log(0)Аргумент вне области определения функции
list.remove(x): x not in list[1, 2].remove(5)Удаляемого элемента нет в списке
substring not found"hello".index("z")str.index() не нашёл подстроку — используйте find
time data '...' does not match format '...'strptime("2026-10-09", ...)Формат в strptime() не совпадает со строкой
max() iterable argument is emptymax([])Пустая последовательность — передайте default
The truth value of an array ... is ambiguousif np_array > 3:Условие по массиву NumPy или Series pandas
I/O operation on closed file.f.read() после f.close()Работа с файлом вне блока with

Важно: в Python 3.14 часть сообщений стала подробнее. Например, math domain error превратилась в expected a nonnegative input, got -1.0, а ошибка распаковки сообщает и ожидаемое, и фактическое число значений. Если текст ошибки у вас отличается от статьи, сначала проверьте версию Python. Ниже приведены оба варианта.

Что означает ValueError

ValueError — встроенное исключение, наследник Exception. Его выбрасывают, когда тип аргумента верный, а значение — нет, и для ситуации нет более точного исключения вроде IndexError или KeyError. Строка "12,5" остаётся строкой, и int() строки принимает, но десятичную запись с запятой разобрать не может.

Как выглядит ошибка целиком:

text = "12,5"
price = int(text)
Traceback (most recent call last):
  File "C:\projects\shop\app.py", line 2, in <module>
    price = int(text)
            ^^^^^^^^^
ValueError: invalid literal for int() with base 10: '12,5'

Последняя строка — тип и сообщение, строки выше — файл и номер строки, где ошибка возникла. Подробно о чтении traceback и отладке — в статье как читать ошибки в Python.

У ValueError есть подклассы, которые вы встретите под своими именами:

  • UnicodeDecodeError и UnicodeEncodeError — ошибки кодировки при чтении и записи текста;
  • json.JSONDecodeError — некорректный JSON в json.loads().

Поэтому except ValueError перехватывает и их:

import json

print(issubclass(json.JSONDecodeError, ValueError))  # → True
print(issubclass(UnicodeDecodeError, ValueError))    # → True

invalid literal for int() with base 10

Самый частый вариант. int() разбирает строку как целое число в десятичной системе (base 10 — основание системы счисления) и падает, если в строке есть что-то кроме знака, цифр и пробелов по краям. В конце сообщения в кавычках стоит само значение — с него и начинайте.

int("42")       # → 42
int(" 42\n")    # → 42: пробелы и перевод строки по краям допустимы
int("3.5")      # ValueError: invalid literal for int() with base 10: '3.5'
int("12,5")     # ValueError: invalid literal for int() with base 10: '12,5'
int("1 2")      # ValueError: invalid literal for int() with base 10: '1 2'
int("")         # ValueError: invalid literal for int() with base 10: ''

Частые причины и исправления:

Значение в ошибкеОткуда берётсяИсправление
''Пользователь нажал Enter, пустая строка в файлеПроверить if text: или повторить ввод
'3.5'Дробное числоint(float(text)) или оставить float
'12,5'Десятичная запятаяtext.replace(",", ".") и float()
'1 2'Несколько чисел в одной строкеmap(int, text.split())
'\ufeff42'Невидимый BOM в начале файла из Excel или БлокнотаОткрывать файл с encoding="utf-8-sig"
'FF'Шестнадцатеричное числоУказать основание: int("FF", 16) → 255

Пустая строка: invalid literal for int() with base 10: ”

Пустые кавычки в конце сообщения значат, что в int() пришла пустая строка. Так бывает, когда пользователь нажал Enter без ввода, в файле есть пустая строка (обычно последняя) или поле формы осталось пустым. Пустые строки пропускают явно:

lines = ["10", "", "25", "\n"]
numbers = [int(line) for line in lines if line.strip()]
print(numbers)  # → [10, 25]

Дробное число в int()

int() не округляет строку "3.5" — сначала преобразуйте её во float, затем в int. Учтите, что int() отбрасывает дробную часть, а не округляет:

print(int(float("3.5")))    # → 3
print(round(float("3.5")))  # → 4

Несколько чисел в одной строке

Если на вход подают 1 2 в одной строке (типично для задач на онлайн-платформах), разбейте строку через split():

text = "1 2"
a, b = map(int, text.split())
print(a + b)  # → 3

could not convert string to float

То же самое для float(). Чаще всего виновата десятичная запятая: Python понимает только точку. Вторая причина — пробелы внутри числа, например разделитель тысяч в выгрузке из Excel.

float("12,5")   # ValueError: could not convert string to float: '12,5'
float("1 000")  # ValueError: could not convert string to float: '1 000'
float("")       # ValueError: could not convert string to float: ''

Строку нормализуют перед преобразованием:

def to_float(text: str) -> float:
    cleaned = text.strip().replace(" ", "").replace("\u00a0", "").replace(",", ".")
    return float(cleaned)

print(to_float("12,5"))      # → 12.5
print(to_float("1 000,75"))  # → 1000.75

\u00a0 — неразрывный пробел, которым Excel и сайты часто отделяют тысячи. Если в данных бывают и запятые-разделители тысяч (1,000.75), простой replace их испортит — тогда нужен разбор под конкретный формат.

too many values to unpack и not enough values to unpack

Ошибки распаковки возникают при присваивании вида a, b = ..., когда число переменных слева не совпадает с числом значений справа.

a, b = [1, 2, 3]
# Python 3.12: ValueError: too many values to unpack (expected 2)
# Python 3.14: ValueError: too many values to unpack (expected 2, got 3)

a, b, c = (1, 2)
# ValueError: not enough values to unpack (expected 3, got 2)

Типичные источники:

  • split() вернул другое число частей. Строка "key=value=x" после split("=") даёт три части. Ограничьте разбиение через maxsplit или используйте partition().
  • Цикл по словарю без .items(). for k, v in d: перебирает только ключи и пытается распаковать каждый ключ-строку.
  • Функция вернула не столько значений, сколько вы ждёте.
line = "key=value=x"
key, value = line.split("=", 1)
print(key, value)  # → key value=x

prices = {"apple": 100, "pear": 80}
for name, price in prices.items():
    print(name, price)
# → apple 100
# → pear 80

first, *rest = [1, 2, 3, 4]
print(first, rest)  # → 1 [2, 3, 4]

Звёздочка *rest собирает «лишние» значения в список и снимает ошибку, когда длина заранее неизвестна.

math domain error

Функции модуля math выбрасывают ValueError, если аргумент вне области определения: корень из отрицательного числа, логарифм нуля или отрицательного числа, acos() вне диапазона от −1 до 1.

import math

math.sqrt(-1)
# Python 3.12: ValueError: math domain error
# Python 3.14: ValueError: expected a nonnegative input, got -1.0

math.log(0)
# Python 3.12: ValueError: math domain error
# Python 3.14: ValueError: expected a positive input

Исправление зависит от задачи: проверить аргумент перед вызовом, взять модуль числа или перейти к комплексным числам через модуль cmath:

import cmath

print(cmath.sqrt(-4))  # → 2j

Часто ошибку вызывает погрешность вычислений: math.acos(1.0000000000000002) падает, хотя по смыслу аргумент равен 1. Такое значение ограничивают: math.acos(max(-1.0, min(1.0, x))).

list.remove(x): x not in list

list.remove() удаляет первое вхождение элемента и выбрасывает ValueError, если элемента нет. То же делает list.index():

items = [1, 2, 3]
items.remove(4)
# ValueError: list.remove(x): x not in list

items.index(5)
# Python 3.12: ValueError: 5 is not in list
# Python 3.14: ValueError: list.index(x): x not in list

Проверьте наличие элемента заранее:

items = [1, 2, 3]
if 4 in items:
    items.remove(4)
print(items)  # → [1, 2, 3]

Если нужно удалить все вхождения значения, надёжнее собрать новый список: items = [x for x in items if x != 4].

substring not found

Метод строки str.index() ищет подстроку и падает, если её нет. Метод str.find() делает то же, но возвращает -1:

text = "hello"
print(text.find("z"))  # → -1
text.index("z")        # ValueError: substring not found

Используйте find() или проверку "z" in text, когда отсутствие подстроки — нормальная ситуация, и index() — когда это ошибка в данных.

time data does not match format

datetime.strptime() разбирает строку по шаблону и требует точного совпадения:

from datetime import datetime

datetime.strptime("2026-10-09", "%d.%m.%Y")
# ValueError: time data '2026-10-09' does not match format '%d.%m.%Y'

datetime.strptime("09.10.2026 12:00", "%d.%m.%Y")
# ValueError: unconverted data remains:  12:00

Сравните строку с шаблоном символ за символом: разделители (- или .), порядок дня и месяца, наличие времени. unconverted data remains значит, что начало строки подошло, а в конце остались лишние символы. Для строк в формате ISO 8601 (2026-10-09) удобнее datetime.fromisoformat(). Отдельный случай — несуществующая дата:

from datetime import date

date(2026, 2, 30)
# Python 3.12: ValueError: day is out of range for month
# Python 3.14: ValueError: day 30 must be in range 1..28 for month 2 in year 2026

Коды формата и работа с датами — в статье про datetime в Python.

max() iterable argument is empty

max() и min() не могут выбрать элемент из пустой последовательности. Если пустой список — нормальная ситуация, передайте значение по умолчанию:

scores = []
print(max(scores, default=0))  # → 0
max(scores)                    # ValueError: max() iterable argument is empty

До Python 3.12 сообщение звучало как max() arg is an empty sequence.

NumPy и pandas: truth value is ambiguous

Сравнение массива NumPy с числом даёт не одно значение True или False, а массив из них. Python не знает, считать такой массив истинным, если истинен хотя бы один элемент или все сразу, поэтому if и операторы and/or выбрасывают ValueError:

import numpy as np

a = np.array([1, 5, 10])
if a > 3:
    print("больше трёх")
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Явно укажите, что нужно:

import numpy as np

a = np.array([1, 5, 10])
print((a > 3).any())         # → True: хотя бы один элемент больше 3
print((a > 3).all())         # → False: не все элементы больше 3
print((a > 3) & (a < 8))     # → [False  True False]

В pandas та же ошибка звучит как The truth value of a Series is ambiguous. Чаще всего её вызывает фильтрация через and вместо &. Каждое условие берут в скобки, потому что & связывает сильнее сравнения:

import pandas as pd

df = pd.DataFrame({"age": [17, 25, 40]})
# df[df.age > 18 and df.age < 30]  → ValueError: The truth value of a Series is ambiguous...
print(df[(df.age > 18) & (df.age < 30)])
   age
1   25

Ещё две частые ошибки pandas:

  • Преобразование столбца в число. df["price"].astype(float) падает на первом же значении вроде '2,5'. pd.to_numeric(..., errors="coerce") превращает неразборчивые значения в NaN вместо ошибки.
  • Length of values (2) does not match length of index (3) — новый столбец получает список не той длины, что таблица.
import pandas as pd

prices = pd.Series(["100", "2,5", "abc"])
print(pd.to_numeric(prices.str.replace(",", "."), errors="coerce").tolist())
# → [100.0, 2.5, nan]

Подробнее о библиотеках — в статьях NumPy в Python и pandas для анализа данных.

ValueError и TypeError: в чём разница

Оба исключения сообщают о неподходящем аргументе, но о разном. TypeError — тип вообще не тот: функция не умеет работать с объектами такого вида. ValueError — тип подходит, но конкретное значение недопустимо.

ВызовИсключениеПочему
int("abc")ValueErrorСтроку int() принимает, эту — разобрать нельзя
int(None)TypeErrorNone в int() не передают вовсе
int([1])TypeErrorСписок не преобразуется в число
math.sqrt(-1)ValueErrorЧисло подходит, отрицательное — нет
"5" + 1TypeErrorСтроку нельзя сложить с числом
int(None)
# TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

Когда одна и та же строка кода может выбросить оба исключения (например, значение пришло из JSON и бывает None), перехватывайте их вместе: except (ValueError, TypeError):. Частые причины TypeError разобраны в отдельной статье про TypeError в Python.

Как обработать ValueError: проверка или try/except

Для преобразования строк в числа надёжнее попытаться выполнить преобразование и перехватить ошибку, чем проверять строку заранее. Цикл, который просит ввод, пока не получит целое число:

while True:
    text = input("Возраст: ")
    try:
        age = int(text)
        break
    except ValueError:
        print(f"Нужно целое число, получено: {text!r}")

print(f"Через год вам будет {age + 1}")
Возраст: двадцать
Нужно целое число, получено: 'двадцать'
Возраст:
Нужно целое число, получено: ''
Возраст: 25
Через год вам будет 26

Запись {text!r} выводит строку через repr(), в кавычках. Так видны пустые строки, пробелы и невидимые символы, которые в обычном print() незаметны.

Проверка через str.isdigit() выглядит проще, но отклоняет обычные числа и пропускает неподходящие символы:

for s in ["42", "-5", "3.5", "²"]:
    print(repr(s), s.isdigit())
# → '42' True
# → '-5' False   — отрицательное число отклонено
# → '3.5' False  — дробь отклонена
# → '²' True     — но int("²") выбросит ValueError

Правила, которые избавляют от лишних проблем:

  • Держите в try только строку, которая может выбросить ValueError, а не весь блок кода — иначе вы перехватите ошибку из другого места.
  • Перехватывайте ValueError, а не Exception и не голый except: — так не скроются чужие ошибки и опечатки.
  • Не «глотайте» ошибку молча: выведите сообщение, запишите в лог через logging.exception() или выбросьте исключение дальше.

Полный синтаксис с else, finally и перехватом нескольких типов — в статье про try/except в Python.

Как вызвать ValueError в своём коде

Выбрасывайте ValueError, когда функция получила значение правильного типа, но недопустимое по смыслу: отрицательную цену, процент больше 100, пустое имя. В сообщение включайте само значение — оно сэкономит время при отладке.

def set_discount(percent: int) -> int:
    if not 0 <= percent <= 100:
        raise ValueError(f"Скидка должна быть от 0 до 100, получено {percent}")
    return percent

set_discount(150)
# ValueError: Скидка должна быть от 0 до 100, получено 150

Если ошибка возникла при разборе данных, сохраните исходную причину через raise ... from, а вызывающему коду отдайте понятное сообщение:

def parse_port(text: str) -> int:
    try:
        port = int(text)
    except ValueError as e:
        raise ValueError(f"Порт должен быть числом, получено {text!r}") from e
    if not 1 <= port <= 65535:
        raise ValueError(f"Порт вне диапазона 1–65535: {port}")
    return port

print(parse_port("8000"))  # → 8000

Не выбрасывайте ValueError для неверного типа: если функция ждёт число, а пришёл список, честнее выбросить TypeError. Для доменных ошибок можно объявить свой класс-наследник — class InvalidPriceError(ValueError): ... — тогда его поймает и except InvalidPriceError, и общий except ValueError. Библиотека Pydantic превращает ValueError из валидаторов в понятную ошибку валидации с указанием поля.

Частые вопросы

Почему int(input()) выдаёт invalid literal for int() with base 10: ”?

input() вернул пустую строку: вы нажали Enter без ввода, программа получает ввод из пустого файла или IDE не передала ввод в программу. Проверьте, что вводите значение в той же консоли, где запущен скрипт, и оберните преобразование в цикл с try/except ValueError, как в примере выше.

Как узнать, какое именно значение вызвало ValueError?

В сообщениях int(), float() и strptime() значение уже стоит в кавычках в конце строки. Если сообщение его не содержит, выведите переменную перед проблемной строкой через print(repr(value)) или print(f"{value!r}"): repr() покажет пробелы, \n, \t и символ BOM \ufeff.

Перехватывает ли except ValueError ошибки JSON и кодировки?

Да. json.JSONDecodeError, UnicodeDecodeError и UnicodeEncodeError — подклассы ValueError, поэтому except ValueError поймает и их. Если обработка должна различаться, ставьте более узкий except выше общего.

Что значит ValueError: Field ‘id’ expected a number but got ‘abc’ в Django?

В фильтр ORM по числовому полю попала строка, которую нельзя преобразовать в число, например User.objects.filter(pk="abc"). Обычно значение пришло из GET-параметра или URL без проверки. Используйте конвертер <int:pk> в маршруте или проверяйте параметр через int() в try/except и возвращайте ошибку 404 или 400.

Почему текст ошибки отличается от того, что пишут в интернете?

Сообщения меняются между версиями Python. В 3.14 вместо math domain error выводится expected a nonnegative input, got -1.0, вместо 5 is not in list — list.index(x): x not in list, а распаковка показывает фактическое число значений. Тип исключения при этом остаётся ValueError, и except ValueError работает во всех версиях.

Как перевести строку с запятой в число?

Замените запятую на точку: float("12,5".replace(",", ".")) → 12.5. Для pandas при чтении CSV укажите pd.read_csv("file.csv", sep=";", decimal=",") — тогда столбцы с десятичной запятой сразу станут числами.

Итог

  • ValueError — тип аргумента верный, значение недопустимое: int("abc"), math.sqrt(-1), [1, 2].remove(5).
  • Причину ищите в последней строке traceback; значение из сообщения выводите через repr(), чтобы увидеть пробелы и невидимые символы.
  • Для int() и float() частые виновники — пустая строка, дробь, запятая, несколько чисел в строке и BOM.
  • Ошибки распаковки снимают split(..., 1), .items() и *rest; проблемы NumPy и pandas — &, |, .any(), .all() и pd.to_numeric(errors="coerce").
  • Пользовательский ввод проверяйте через try/except ValueError, а не isdigit().
  • В своём коде выбрасывайте ValueError с недопустимым значением в сообщении, а TypeError — для неверного типа.
  • #Python
  • #ValueError
  • #Исключения
  • #Отладка
  • #try except
↑ ↓ выборEnter открытьEsc закрыть