Вопрос

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

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

Это было полезно?

Решение

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

Другие советы

def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

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

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

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

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

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, то у вас возникают гораздо большие проблемы.

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

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

То есть безопасная "оценка"

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)

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

Вам следует рассмотреть возможность использования запятых в строковом представлении числа для таких случаев, как 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 также доступен, но аргумент должен быть целым числом.

Если вы не испытываете отвращения к сторонним модулям, вы могли бы ознакомиться с быстрые номера модуль.Он предоставляет функцию, называемую быстро_реальный это делает именно то, о чем просит этот вопрос, и делает это быстрее, чем реализация на чистом 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

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

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

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

Это хорошо только в том случае, если все они одного типа.

Вопрос кажется немного устаревшим.Но позвольте мне предложить функцию parseStr, которая делает нечто подобное, то есть возвращает integer или float, и если данная строка 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'

В Python, как я могу разобрать числовую строку типа "545.2222" до ее соответствующего значения с плавающей запятой, 542.2222?Или разобрать строку "31" до целого числа 31? Я просто хочу знать, как преобразовать строку с плавающей точкой в float и (отдельно) строку 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 сделать это за вас автоматически с правильным синтаксисом.

Вы можете использовать соответствующие префиксы, чтобы получить автоматическое преобразование в целые числа с следующие литералы.Они действительны для 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

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

В ЯМЛ анализатор может помочь вам определить, к какому типу данных относится ваша строка.Использование 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'>

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

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
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
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')

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

То есть.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)

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

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

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

Например:

>>>float("23.333")
   23.333

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

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

Использование:

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()

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

Использование:

>>> 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'>

Это функция, которая преобразует любой 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

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

def parseIntOrFloat( aString ):
    return eval( aString )

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top