PyQt5 ValueError: не удалось преобразовать строку в float: [duplicate]

Я думаю, ваша проблема в том, что вы путаете оператор присваивания (=) с оператором равенства (== или ===). оператор присваивания левой руки равен тому, что находится в правой части, а оператор равенства (== или ===) фактически проверяет равенство.

1834
задан Steven Vascellaro 15 February 2018 в 17:41
поделиться

21 ответ

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
2092
ответ дан Harley Holcombe 17 August 2018 в 09:26
поделиться
  • 1
    просто интересно, почему в конце концов «04»? почему бы не просто «00»? также моя текущая версия python не имеет «04». – Mangat Rai Modi 17 August 2017 в 15:25
  • 2
    @MangatRaiModi Число плавающих точек по своей сути несовершенно для представления десятичных знаков. Для получения дополнительной информации см. stackoverflow.com/q/21895756/931277 – dokkaebi 18 August 2017 в 21:44
  • 3
    почему не просто int(a), а int(float(a))? – user463035818 26 April 2018 в 14:36
  • 4
    int(a) даст ошибку, что строка не является допустимым целым числом: ValueError: invalid literal for int() with base 10: '545.222', но преобразование из float в int является поддерживаемым преобразованием. – David Parks 7 May 2018 в 17:46
  • 5

В Python, как я могу проанализировать числовую строку, такую ​​как «545.2222», с ее соответствующим значением float, 542.2222? Или проанализировать строку «31» на целое число, 31? Я просто хочу знать, как разбирать строку с плавающей точкой для float и (отдельно) int string для int.

Хорошо, что вы просите сделать это отдельно. Если вы смешиваете их, вы можете настроить себя на проблемы позже. Простой ответ:

"545.2222" для float:

>>> float("545.2222")
545.2222

"31" для целого числа:

>>> int("31")
31

Другие преобразования, ints для и из строк и литералов:

Конверсии из разных баз, и вы должны заранее знать базу (10 по умолчанию). Обратите внимание, что вы можете прикрепить их к тому, что Python ожидает для своих литералов (см. Ниже) или удалить префикс:

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

Если вы не знаете базу заранее, но знаете, что они будут иметь Правильный префикс, Python может сделать это для вас, если вы передадите 0 в качестве базы:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

Литералы без десятичного (то есть целого) из других баз

Если ваша мотивация заключается в том, чтобы ваш собственный код четко представлял жестко заданные конкретные значения, однако вам, возможно, не нужно конвертировать из баз - вы можете позволить Python сделать это для вас автоматически с правильным синтаксисом.

Вы можете использовать префиксы apropos для автоматического преобразования в целые числа с следующими литералами . Они действительны для Python 2 и 3:

Binary, prefix 0b

>>> 0b11111
31

Octal, prefix 0o

>>> 0o37
31

Шестнадцатеричный, prefix 0x

>>> 0x1f
31

Это может быть полезно при описании двоичных флагов, разрешений файлов в коде или шестнадцатеричных значений для цветов - например, не отметить кавычки:

>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215

Создание двусмысленных Python 2, совместимых с Python 3

Если вы видите целое число, которое начинается с 0, в Python 2, это (устаревший) восьмеричный синтаксис.

>>> 037
31

Это плохо, потому что похоже, что значение должно быть 37. Таким образом, в Python 3 теперь появляется SyntaxError:

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Преобразуйте восьмеричные элементы Python 2 в восьмеричные, которые работают как с 2, так и с префиксом 0o:

>>> 0o37
31
17
ответ дан Aaron Hall 17 August 2018 в 09:26
поделиться

Метод Python для проверки, является ли строка плавающей точкой:

def isfloat(value):
  try:
    float(value)
    return True
  except:
    return False

Более длинным и точным именем для этой функции может быть: isConvertibleToFloat(value)

Что такое и не является поплавком в Python может вас удивить:

val                   isfloat(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad

Вы думаете, что знаете, какие цифры? Вы не так хороши, как думаете! Не большой сюрприз.

417
ответ дан cbuchart 17 August 2018 в 09:26
поделиться

float("545.2222") и int(float("545.2222"))

13
ответ дан codelogic 17 August 2018 в 09:26
поделиться
  • 1
    Это даст вам объект с плавающей точкой, если ваша строка имеет значение «0». или «0.0», а не int, который он дает для других допустимых номеров. – Brian 19 December 2008 в 09:42

Это исправленная версия https://stackoverflow.com/a/33017514/5973334

Это попытается проанализировать строку и вернуть либо int, либо float в зависимости от того, что представляет строка. Это может привести к синтаксическим ошибкам синтаксического анализа или , которые имеют некоторое неожиданное поведение .

  def get_int_or_float(v):
        number_as_float = float(v)
        number_as_int = int(number_as_float)
        return number_as_int if number_as_float == number_as_int else 
        number_as_float
3
ответ дан Community 17 August 2018 в 09:26
поделиться
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
445
ответ дан David Jones 17 August 2018 в 09:26
поделиться
  • 1
    неявное смешивание floats / int может приводить к тонким ошибкам из-за возможной потери точности при работе с поплавками или с разными результатами для оператора / на float / ints. В зависимости от контекста может быть предпочтительнее возвращать либо int, либо float, а не оба. – jfs 16 November 2012 в 16:35
  • 2
    @ J.F.Sebastian. Вы совершенно правы, но есть моменты, когда вы хотите, чтобы входные данные определяли, какой из них он будет. Позволяя вводить диктовать, с которым можно хорошо работать с утиным набором. – TimothyAWiseman 5 March 2013 в 23:29
  • 3
    Вы можете вложить другой try, чтобы создать исключение, если оно не конвертируется в float. – iBug 25 January 2018 в 13:31

Python обладает такой большой гибкостью в синтаксическом анализе в одном лайнере.

str = "545.2222"
print ("int: ", + int(float(a)))
print ("float: ", +(float(a)))
3
ответ дан Harry_pb 17 August 2018 в 09:26
поделиться
def num(s):
"""num(s)
num(3),num(3.7)-->3
num('3')-->3, num('3.7')-->3.7
num('3,700')-->ValueError
num('3a'),num('a3'),-->ValueError
num('3e4') --> 30000.0
"""
try:
    return int(s)
except ValueError:
    try:
        return float(s)
    except ValueError:
        raise ValueError('argument is not a string of number')
7
ответ дан Jerry T 17 August 2018 в 09:26
поделиться

Локализация и запятые

Вы должны рассмотреть возможность запятых в строчном представлении числа, для случаев, подобных float("545,545.2222"), который выдает исключение. Вместо этого используйте методы в locale для преобразования строк в числа и правильной интерпретации запятых. Метод locale.atof преобразуется в float за один шаг после того, как языковой стандарт был установлен для обозначения желаемого номера.

Пример 1 - Соглашения о числах в Соединенных Штатах

В Соединенных Штатах и в Великобритании запятые могут использоваться как разделитель тысяч. В этом примере с американской локалью запятая обрабатывается должным образом в качестве разделителя:

>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>

Пример 2 - Европейские условные обозначения

В большинстве стран world , запятые используются для десятичных знаков вместо периодов. В этом примере с французским языком, запятая корректно обрабатывается как десятичная метка:

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

Также доступен метод locale.atoi, но аргумент должен быть целым числом.

45
ответ дан Mark Chackerian 17 August 2018 в 09:26
поделиться

Для этого нужно учитывать округление.

I.e. int (5.1) => 5 int (5.6) => 5 - неверно, должно быть 6, поэтому мы делаем int (5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
7
ответ дан Nick 17 August 2018 в 09:26
поделиться
  • 1
    Хорошая точка зрения. Это вызывает инфляцию, поэтому Python 3 и другие современные языки используют округление банкира. – Cees Timmerman 4 October 2012 в 13:58
  • 2
    Этот ответ неверен (как изначально написано). Он смешивает два случая int и float. И это даст исключение, когда n является строкой, как требуется OP. Возможно, вы имели в виду: Когда желателен результат int, round должен быть выполнен ПОСЛЕ конвертации в float. Если функция должна ВСЕГДА возвращать int, тогда вам не нужна за исключением части - тело всей функции может быть int(round(float(input))). Если функция должна возвращать int, если это возможно, в противном случае - float, то исходное решение javier будет правильным! – ToolmakerSteve 13 December 2013 в 08:02

Вот еще одна интерпретация вашего вопроса (намек: он неопределенный). Возможно, вы ищете что-то вроде этого:

def parseIntOrFloat( aString ):
    return eval( aString )

Он работает следующим образом ...

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

Теоретически существует уязвимость в отношении инъекций. Строка может быть, например, "import os; os.abort()". Однако, без какой-либо информации о том, откуда взялась эта строка, существует теоретическая спекуляция. Поскольку вопрос неопределен, совершенно неясно, существует ли эта уязвимость или нет.

22
ответ дан Peter Mortensen 17 August 2018 в 09:26
поделиться
  • 1
    Даже если его вход на 100% безопасен, eval() превышает 3 раза медленнее, чем try: int(s) except: float(s). – Cees Timmerman 4 October 2012 в 14:12
  • 2
    1e3 - это число в python, но строка в соответствии с вашим кодом. – Cees Timmerman 4 October 2012 в 14:24
  • 3
    – U9-Forward 1 October 2018 в 01:26

В typecast в python используются функции конструктора типа, передавая строку (или любое другое значение, которое вы пытаетесь выполнить) в качестве параметра.

Например:

>>>float("23.333")
   23.333

За кулисами python вызывает метод objects __float__, который должен возвращать float-представление параметра. Это особенно эффективно, так как вы можете определить свои собственные типы (используя классы) с помощью метода __float__, чтобы он мог быть введен в float с использованием float (myobject).

2
ответ дан qwerty12345 17 August 2018 в 09:26
поделиться
float(x) if '.' in x else int(x)
74
ответ дан S.Lott 17 August 2018 в 09:26
поделиться
  • 1
    Nitpick: не работает для экстремальных случаев, таких как float («2e-3») – Emile 8 December 2010 в 15:22
  • 2
    Примечание: будьте осторожны, когда имеете дело с количеством денег, переданным в виде строк, так как некоторые страны используют & quot ;, & quot; как десятичные разделители – Ben G 8 July 2011 в 12:17
  • 3
    @Emile: Я бы не назвал & quot; 2e-3 & quot; «крайний случай». Этот ответ просто сломан. – jchl 7 September 2011 в 11:05
  • 4
    @BenG НЕ управляйте деньгами как поплавок. Это требует неприятностей. Используйте десятичные деньги! (Но ваш комментарий о ',' по-прежнему действителен и важен) – ToolmakerSteve 13 December 2013 в 08:10
  • 5
    Не забывайте, что "не число" (NaN) и +/- бесконечность также являются действительными значениями float. Таким образом, float("nan") - вполне допустимое значение float, которое вышеприведенный ответ не будет вообще поймать – Ronny Andersson 23 August 2017 в 14:12

Если вы не прочь от сторонних модулей, вы можете проверить модуль fastnumbers . Он предоставляет функцию, называемую fast_real , которая делает именно то, что задает этот вопрос, и делает это быстрее, чем реализация pure-Python:

>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int
21
ответ дан SethMMorton 17 August 2018 в 09:26
поделиться

Я использую эту функцию для этого

import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return

. Он преобразует строку в свой тип

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float
8
ответ дан Shameem 17 August 2018 в 09:26
поделиться

Это еще один метод, который заслуживает упоминания здесь ast.literal_eval :

. Это можно использовать для безопасной оценки строк, содержащих выражения Python, из ненадежных источников без необходимость разбирать значения.

То есть безопасный 'eval'

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
104
ответ дан Stefano 17 August 2018 в 09:26
поделиться
  • 1
    это not хорошее решение проблемы. Он отлично работает в Python 2, но в Python 3 происходит следующее: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Чтобы выяснить, почему это проблема, если вы хотите, чтобы он оставлял номера телефонов в одиночку и не предполагал, что они являются математическими выражениями, тогда этот подход не для вас , – royce3 16 January 2018 в 17:14
  • 2
    @ royce3 Да, это хороший момент, и пользователи должны остерегаться. Поведение было первоначально изменено для решения некоторых проблем с разбором сложных литералов. Вероятно, это ошибка в ast.literal_eval, и здесь обсуждался . – wim 16 January 2018 в 18:57

Я удивлен, что никто не упоминает регулярное выражение, потому что иногда строка должна быть подготовлена ​​и нормализована до того, как будет использована функция

import re
def parseNumber(value, as_int=False):
    try:
        number = float(re.sub('[^.\-\d]', '', value))
        if as_int:
            return int(number + 0.5)
        else:
            return number
    except ValueError:
        return float('nan')  # or None if you wish

:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

и, кстати, что-то убедитесь, что у вас есть номер:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal
3
ответ дан Sławomir Lenart 17 August 2018 в 09:26
поделиться
def get_int_or_float(v):
    number_as_float = float(v)
    number_as_int = int(number_as_float)
    return number_as_int if number_as_float == number_as_int else number_as_float
11
ответ дан Totoro 17 August 2018 в 09:26
поделиться
  • 1
    Зачем вам поднимать в разделе except, если вы ничего не делаете? float () поднимет вас. – Greg0ry 19 March 2016 в 21:30
  • 2
    вы правы, я думаю, что я скопировал и вставлял из функциональности, что я поднимал конкретное исключение. будет редактировать. благодаря – Totoro 2 November 2016 в 16:18
  • 3
    Это попытается проанализировать строку и вернуть либо int, либо float в зависимости от того, что представляет строка. Это может привести к синтаксическому анализу исключений или [иметь какое-то неожиданное поведение] [1]. – Kuzeko 18 May 2017 в 07:28
22
ответ дан Peter Mortensen 6 September 2018 в 07:07
поделиться
23
ответ дан Peter Mortensen 29 October 2018 в 13:48
поделиться
0
ответ дан Unheilig 29 October 2018 в 13:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: