Как мне разобрать строку на float или int?

Как в Python разобрать числовую строку, например "545.2222", на соответствующее ей значение с плавающей запятой, 545.2222? Или преобразовать строку "31" в целое число 31?

Я просто хочу знать, как разобрать float str на float и (отдельно) int str на int.


person Tristan Havelick    schedule 19.12.2008    source источник
comment
Как правило, если у вас есть объект в Python и вы хотите преобразовать в этот тип объекта, вызовите для него type(my_object). Результат обычно можно вызвать как функцию для преобразования. Например, type(100) приводит к int, поэтому вы можете вызвать int(my_object), чтобы попытаться преобразовать my_object в целое число. Это не всегда работает, но это хорошее первое предположение при кодировании.   -  person robertlayton    schedule 05.07.2018
comment
@tcpaiva ValueError: invalid literal for int() with base 10: '1.5'.   -  person marcelm    schedule 14.10.2020


Ответы (27)


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

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

Более длинное и точное название этой функции могло бы быть: is_convertible_to_float(value)

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

val                   is_float(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

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

Не используйте этот код в жизненно важном программном обеспечении!

Таким образом, улавливание широких исключений, уничтожение канареек и поглощение исключения создает крошечный шанс того, что допустимое значение с плавающей запятой в виде строки вернет false. float(...) строка кода может выйти из строя по любой из тысячи причин, не имеющих ничего общего с содержимым строки. Но если вы пишете жизненно важное программное обеспечение на языке прототипов типа «утка», таком как Python, то у вас возникают гораздо более серьезные проблемы.

person Eric Leschinski    schedule 05.01.2014
comment
Итак, true становится 1, то есть я унаследовал от C ++, я думаю - person FindOutIslamNow; 11.09.2018
comment
Я опубликовал этот ответ в 2014 году. Этот UTF-8 глиф для китайского 4 трансформировался на протяжении многих лет в зависимости от того, как разработчики stackoverflow меняют свою схему кодировки символов в своем стеке инструментов Microsoft. Любопытно наблюдать, как с годами все меняется, поскольку новые схемы конверсии отстаивают свои новые идеологии. Но да, любой символ UTF-8 для восточно-восточного числового значения не является поплавком Python. Bazinga. - person Eric Leschinski; 04.12.2018
comment
как это может быть так поддержано, за таким широким исключением? - person E.Serra; 13.03.2019
comment
Все, что между ними есть пробелы, нельзя преобразовать, например "- 12.3" и "45 e6". - person Simon; 12.08.2019
comment
Это предложение except должно быть ограничено TypeError, ValueError - person wim; 31.08.2019
comment
Вместо is_convertible_to_float лучше было бы can_be_float - person godfryd; 14.07.2021
comment
Г-н месекс назовите эту функцию. Ооо эээ может !!! - person Eric Leschinski; 14.07.2021

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

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

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

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
person wim    schedule 01.03.2012
comment
это не хорошее решение проблемы. Он отлично работает в Python 2, но в Python 3 происходит следующее: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Чтобы прояснить, почему это проблема, если вы хотите, чтобы телефонные номера оставались в покое и не предполагали, что они являются математическими выражениями, тогда этот подход не для вас. - person royce3; 16.01.2018
comment
@ royce3 Да, это хороший аргумент, и пользователям следует остерегаться. Изначально поведение было изменено для решения некоторых проблем с синтаксическим анализом сложных литералов. Возможно, это ошибка в ast.literal_eval, и она обсуждалась здесь. - person wim; 16.01.2018

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

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

Пример 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 - Европейские соглашения о нумерации

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

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

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

person Mark Chackerian    schedule 23.07.2013
comment
Это кажется идеальным решением, когда вы знаете, следует ли возвращать float или int, но как вы можете заставить это возвращать int только в том случае, если int был передан? Например, x = '1'; locale.atof(x) возвращает 1.0, когда я действительно хочу 1. - person user5359531; 02.01.2019
comment
Я полагаю, что, используя метод Дино, можно было бы использовать что-то вроде этого: locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x) - person user5359531; 02.01.2019
comment
Я бы порекомендовал использовать метод Хавьера, описанный выше (упаковка locale.atoi при попытке и использование locale.atof при исключении - это, вероятно, более читабельно. - person Mark Chackerian; 02.01.2019

Если вы не против сторонних модулей, вы можете проверить модуль fastnumbers. Он предоставляет функцию под названием fast_real, которая делает именно то, что задают вопрос. запрашивает и делает это быстрее, чем реализация на чистом 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
person SethMMorton    schedule 14.08.2014

Пользователи codelogic и harley верны, но имейте в виду, если вы знаете, что строка является целым числом (например, 545), вы можете вызвать int ("545") без первого литье на плаву.

Если ваши строки находятся в списке, вы также можете использовать функцию карты.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

Только хорошо, если все они одного типа.

person Community    schedule 19.12.2008

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

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

"545.2222" плавать:

>>> float("545.2222")
545.2222

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

>>> int("31")
31

Другие преобразования, целые числа в строки и литералы и из них:

Конверсии из разных баз, и вы должны знать базу заранее (по умолчанию 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:

Двоичный, префикс 0b

>>> 0b11111
31

Восьмеричный, префикс 0o

>>> 0o37
31

Шестнадцатеричный, префикс 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, так и в 3, с префиксом 0o:

>>> 0o37
31
person Aaron Hall    schedule 23.07.2015

Вопрос кажется староватым. Но позвольте мне предложить функцию parseStr, которая делает что-то подобное, то есть возвращает целое число или число с плавающей запятой, и если данная строка ASCII не может быть преобразована ни в одну из них, она возвращает ее нетронутой. Код, конечно, можно настроить так, чтобы он делал только то, что вы хотите:

   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
   ...                      int(x) or x.isalnum() and x or \
   ...                      len(set(string.punctuation).intersection(x)) == 1 and \
   ...                      x.count('.') == 1 and float(x) or x
   >>> parseStr('123')
   123
   >>> parseStr('123.3')
   123.3
   >>> parseStr('3HC1')
   '3HC1'
   >>> parseStr('12.e5')
   1200000.0
   >>> parseStr('12$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'
person krzym    schedule 28.09.2011
comment
1e3 - это число в Python, но это строка в соответствии с вашим кодом. - person Cees Timmerman; 04.10.2012
comment
Я предпочитаю этот ответ. - person enchance; 17.07.2020

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

person codelogic    schedule 19.12.2008
comment
Это даст вам объект с плавающей запятой, если ваша строка окажется равной 0 или 0,0, а не int, который она дает для других действительных чисел. - person Brian; 19.12.2008

Парсер YAML может помочь вам выяснить, к какому типу данных относится ваша строка. Используйте yaml.load(), а затем вы можете использовать type(result) для проверки типа:

>>> import yaml

>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>

>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>

>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>
person Rafe    schedule 16.04.2013

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

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
person Shameem    schedule 09.07.2017
comment
Обратите внимание, что parse_str(' 1') (с пробелом) вернет None, а не 1. - person musiphil; 02.05.2019

Передайте свою строку в эту функцию:

def string_to_number(str):
  if("." in str):
    try:
      res = float(str)
    except:
      res = str  
  elif(str.isdigit()):
    res = int(str)
  else:
    res = str
  return(res)

Он вернет int, float или string в зависимости от того, что было передано.

строка, имеющая тип int

print(type(string_to_number("124")))
<class 'int'>

строка с плавающей точкой

print(type(string_to_number("12.4")))
<class 'float'>

строка, которая является строкой

print(type(string_to_number("hello")))
<class 'str'>

строка, похожая на плавающую

print(type(string_to_number("hel.lo")))
<class 'str'>
person Cybernetic    schedule 10.12.2019

Вы должны принять во внимание округление, чтобы сделать это правильно.

Т.е. 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)
person Nick    schedule 21.10.2010
comment
Хорошая точка зрения. Однако это вызывает инфляцию, поэтому Python 3 и в других современных языках используется банковское округление. - person Cees Timmerman; 04.10.2012
comment
Этот ответ неверен (как написано изначально). Он смешивает два случая int и float. И он выдаст исключение, когда n является строкой, как требуется OP. Возможно, вы имели в виду: Когда желателен результат int, round следует выполнять ПОСЛЕ преобразования в число с плавающей запятой. Если функция должна ВСЕГДА возвращать int, тогда вам не нужна исключительная часть - все тело функции может быть int(round(float(input))). Если функция должна возвращать int, если это возможно, в противном случае - float, то исходное решение Хавьера правильное! - person ToolmakerSteve; 13.12.2013

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

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
person Sławomir Lenart    schedule 12.07.2017

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

Например:

>>>float("23.333")
   23.333

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

person kCODINGeroo    schedule 01.07.2018

Обрабатывает шестнадцатеричные, восьмеричные, двоичные, десятичные и числа с плавающей запятой

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

def to_number(n):
    ''' Convert any number representation to a number 
    This covers: float, decimal, hex, and octal numbers.
    '''

    try:
        return int(str(n), 0)
    except:
        try:
            # python 3 doesn't accept "010" as a valid octal.  You must use the
            # '0o' prefix
            return int('0o' + n, 0)
        except:
            return float(n)

Эти выходные данные тестового примера иллюстрируют то, о чем я говорю.

======================== CAPTURED OUTPUT =========================
to_number(3735928559)   = 3735928559 == 3735928559
to_number("0xFEEDFACE") = 4277009102 == 4277009102
to_number("0x0")        =          0 ==          0
to_number(100)          =        100 ==        100
to_number("42")         =         42 ==         42
to_number(8)            =          8 ==          8
to_number("0o20")       =         16 ==         16
to_number("020")        =         16 ==         16
to_number(3.14)         =       3.14 ==       3.14
to_number("2.72")       =       2.72 ==       2.72
to_number("1e3")        =     1000.0 ==       1000
to_number(0.001)        =      0.001 ==      0.001
to_number("0xA")        =         10 ==         10
to_number("012")        =         10 ==         10
to_number("0o12")       =         10 ==         10
to_number("0b01010")    =         10 ==         10
to_number("10")         =         10 ==         10
to_number("10.0")       =       10.0 ==         10
to_number("1e1")        =       10.0 ==         10

Вот тест:

class test_to_number(unittest.TestCase):

    def test_hex(self):
        # All of the following should be converted to an integer
        #
        values = [

                 #          HEX
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0xDEADBEEF  , 3735928559), # Hex
                ("0xFEEDFACE", 4277009102), # Hex
                ("0x0"       ,          0), # Hex

                 #        Decimals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (100         ,        100), # Decimal
                ("42"        ,         42), # Decimal
            ]



        values += [
                 #        Octals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0o10        ,          8), # Octal
                ("0o20"      ,         16), # Octal
                ("020"       ,         16), # Octal
            ]


        values += [
                 #        Floats
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (3.14        ,       3.14), # Float
                ("2.72"      ,       2.72), # Float
                ("1e3"       ,       1000), # Float
                (1e-3        ,      0.001), # Float
            ]

        values += [
                 #        All ints
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                ("0xA"       ,         10), 
                ("012"       ,         10), 
                ("0o12"      ,         10), 
                ("0b01010"   ,         10), 
                ("10"        ,         10), 
                ("10.0"      ,         10), 
                ("1e1"       ,         10), 
            ]

        for _input, expected in values:
            value = to_number(_input)

            if isinstance(_input, str):
                cmd = 'to_number("{}")'.format(_input)
            else:
                cmd = 'to_number({})'.format(_input)

            print("{:23} = {:10} == {:10}".format(cmd, value, expected))
            self.assertEqual(value, expected)
person shrewmouse    schedule 22.11.2019

Это исправленная версия 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
person Kuzeko    schedule 18.05.2017

Использовать:

def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()

Это самый питонический способ, который я мог придумать.

person SeasonalShot    schedule 09.10.2016
comment
Генератор останавливается после первой интерпретации float. Блок trycatch, вероятно, должен находиться внутри цикла for. - person musiphil; 02.05.2019

Использовать:

>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>
person Community    schedule 11.09.2016

Это функция, которая преобразует любой object (а не только str) в int или float в зависимости от того, выглядит ли фактическая предоставленная строка как int или float. Кроме того, если это объект, который имеет методы __float и __int__, по умолчанию используется __float__

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x
person Abhishek Bhatia    schedule 12.08.2019

для числа и символа вместе:

string_for_int = "498 results should get"
string_for_float = "498.45645765 results should get"

первый импорт re:

 import re

 #for get integer part:
 print(int(re.search(r'\d+', string_for_int).group())) #498

 #for get float part:
 print(float(re.search(r'\d+\.\d+', string_for_float).group())) #498.45645765

для легкой модели:

value1 = "10"
value2 = "10.2"
print(int(value1)) #10
print(float(value2)) #10.2
person mamal    schedule 19.07.2020

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

def parse_num(candidate):
    """parse string to number if possible
    work equally well with negative and positive numbers, integers and floats.

    Args:
        candidate (str): string to convert

    Returns:
        float | int | None: float or int if possible otherwise None
    """
    try:
        float_value = float(candidate)
    except ValueError:
        return None

    # optional part if you prefer int to float when decimal part is 0 
    if float_value.is_integer():
        return int(float_value)
    # end of the optional part

    return float_value

# test
candidates = ['34.77', '-13', 'jh', '8990', '76_3234_54']
res_list = list(map(parse_num, candidates))
print('Before:')
print(candidates)
print('After:')
print(res_list)

выход:

Before:
['34.77', '-13', 'jh', '8990', '76_3234_54']
After:
[34.77, -13, None, 8990, 76323454]
person Sameh Farouk    schedule 15.07.2021

Используя методы int и float, мы можем преобразовать строку в integer и float.

s="45.8"
print(float(s))

y='67'
print(int(y))
person Shekku Joseph    schedule 26.05.2020
comment
Этот ответ не добавляет ничего нового. См., Например, это ответ, который дает ту же информацию и многое другое. - person Georgy; 26.05.2020

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

def parseIntOrFloat( aString ):
    return eval( aString )

Это работает так ...

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

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

person S.Lott    schedule 19.12.2008
comment
Даже если его ввод на 100% безопасен, eval() более чем в 3 раза медленнее, чем try: int(s) except: float(s). - person Cees Timmerman; 04.10.2012
comment
Что ж, eval - плохая практика (вы должны знать, потому что у вас 310k репутации) - person U11-Forward; 01.10.2018

person    schedule
comment
просто интересно, почему в конце стоит «04»? почему не просто «00»? также моя текущая версия python не имеет «04». - person Mangat Rai Modi; 17.08.2017
comment
@MangatRaiModi Числа с плавающей запятой по своей сути несовершены для представления десятичных дробей. Для получения дополнительной информации см. stackoverflow.com/q/21895756/931277. - person dokkaebi; 19.08.2017
comment
почему не просто int(a), а int(float(a))? - person 463035818_is_not_a_number; 26.04.2018
comment
int(a) выдаст ошибку о том, что строка не является допустимым целым числом: ValueError: invalid literal for int() with base 10: '545.222', но преобразование из числа с плавающей запятой в int является поддерживаемым преобразованием. - person David Parks; 07.05.2018
comment
Вы должны обращаться с ValueError, если хотите быть в безопасности - person Joe Bobson; 09.09.2018
comment
@MangatRaiModi python некоторое время назад изменил свою политику округления для чисел с плавающей запятой, раньше он использовал фиксированное количество цифр, теперь он использует кратчайшее представление туда и обратно. - person plugwash; 22.08.2019
comment
int(a) сейчас работает (Python 3.9) - person PatrickT; 28.06.2021

person    schedule
comment
неявное смешивание чисел с плавающей запятой и целых чисел может привести к незначительным ошибкам из-за возможной потери точности при работе с числами с плавающей запятой или к другим результатам для оператора / с числами с плавающей запятой / целым числом. В зависимости от контекста может быть предпочтительнее возвращать либо int, либо float, а не то и другое одновременно. - person jfs; 16.11.2012
comment
@ J.F.Sebastian: Вы совершенно правы, но бывают случаи, когда вы хотите, чтобы исходные данные диктовали, какой именно. Позволяя вводу диктовать, какой из них может хорошо работать с утиным набором текста. - person TimothyAWiseman; 06.03.2013
comment
Вы можете вложить еще один try, чтобы генерировать исключение, когда оно не может быть преобразовано в плавающее. - person iBug; 25.01.2018
comment
Ошибка с s = u'\u0000' - person Matt Hancock; 12.11.2018
comment
@iBug Хорошая идея! Рекомендую закинуть ValueError в соответствующий except: P - person marcelm; 06.02.2019
comment
@ Мэтт А почему бы и нет? NUL - это не число. Если вы хотите преобразовать его в 0, вам нужно будет пойти другим путем, например int(u'\x00'.encode('hex'), 16). - person wjandrea; 27.04.2021

person    schedule
comment
Примечание: будьте осторожны при работе с суммой денег, переданной в виде строк, как в некоторых странах, в качестве десятичных разделителей. - person Ben G; 08.07.2011
comment
@ Эмиль: Я бы не назвал 2e-3 крайним случаем. Этот ответ просто неверен. - person jchl; 07.09.2011
comment
@BenG НЕ манипулируйте деньгами как плавающими. Это напрашивается на неприятности. Используйте десятичную дробь для денег! (Но ваш комментарий по поводу ',' по-прежнему актуален и важен) - person ToolmakerSteve; 13.12.2013
comment
Не забывайте, что не число (NaN) и +/- бесконечность также являются допустимыми значениями с плавающей запятой. Итак, float("nan") - это совершенно допустимое значение с плавающей запятой, которое в приведенном выше ответе вообще не улавливается. - person Ronny Andersson; 23.08.2017
comment
Легко взламывается по IP-адресу - 192.168.0.1; или "This is not a good approach. :)" - person Todor Minakov; 13.01.2019

person    schedule
comment
Зачем вам повышать в своем разделе except, если вы там ничего не делаете? float () поднимет за вас. - person Greg0ry; 19.03.2016
comment
вы правы, я полагаю, что я скопировал и вставил из функции, которая вызывала конкретное исключение. буду редактировать. Благодарность - person Totoro; 02.11.2016
comment
Это попытается проанализировать строку и вернуть либо int, либо float в зависимости от того, что представляет собой строка. Это может вызвать исключения при синтаксическом анализе или [иметь непредвиденное поведение] [1]. - person Kuzeko; 18.05.2017