Frage

In Python, wie kann ich eine Ziffernfolge wie "545.2222" zu seinem entsprechenden Float-Wert, 545.2222 analysieren? Oder analysieren Sie die Zeichenfolge "31" auf eine ganze Zahl, 31?

Ich will nur wissen, wie ein float str zu einem float zu analysieren, und (separat) ein int str zu einem int.

War es hilfreich?

Lösung

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

Andere Tipps

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

Python-Methode zu überprüfen, ob eine Zeichenfolge ein Schwimmer ist:

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

Eine längere und genauere Bezeichnung für diese Funktion könnte sein: is_convertible_to_float(value)

Was ist, und ist kein Schwimmer in Python Sie überraschen kann:

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

Sie denken, Sie wissen, welche Zahlen sind? Sie sind nicht so gut, wie Sie denken! Nicht große Überraschung.

Verwenden Sie diesen Code nicht auf lebenswichtige Software!

Fangen breite Ausnahmen auf diese Weise, Kanarienvögel zu töten und die Ausnahme gobbling schafft eine winzige Chance, dass ein gültiger Schwimmer als Zeichenfolge falsch zurück. Die float(...) Codezeile kann aus einem von tausend Gründen gescheitert, die nichts mit dem Inhalt der Zeichenfolge zu tun. Aber wenn Sie schreiben lebenskritische Software in einer Ente-Eingabe Prototyp Sprache wie Python, dann haben Sie, viel größere Probleme.

Dies ist eine weitere Methode, die hier erwähnt zu werden verdient, ast.literal_eval :

  

Dies kann zur sicheren Auswertung von Zeichenketten enthalten Python-Ausdrücke aus nicht vertrauenswürdigen Quellen, ohne dass sich die Werte analysieren, verwendet werden.

Das heißt, ein sicherer 'eval'

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

Lokalisierung und Komma

Sie sollten die Möglichkeit Kommas in der String-Darstellung einer Zahl, für Fälle wie float("545,545.2222") betrachten, die eine Ausnahme auslöst. Verwenden Sie stattdessen Methoden in locale die Strings in Zahlen zu konvertieren und Kommata richtig zu interpretieren. Die locale.atof Verfahren wandelt in einem Schwimmer in einem Schritt, sobald die locale wurde für die gewünschte Anzahl Konvention festgelegt wurde.

Beispiel 1 - Vereinigte Staaten Zahl Konventionen

In den Vereinigten Staaten und Großbritannien können Kommas als Tausendertrennzeichen verwendet werden. In diesem Beispiel mit amerikanischen locale, wird das Komma richtig als Separator behandelt:

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

Beispiel 2 - Europäische Zahl Konventionen

In der Mehrheit der Länder der Welt , werden Kommas für Dezimalpunkte verwenden anstelle von Perioden. In diesem Beispiel mit Französisch locale, wird das Komma korrekt als Dezimalzeichen behandelt:

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

Das Verfahren locale.atoi ist ebenfalls verfügbar, aber das Argument sollte eine ganze Zahl sein.

Wenn Sie nicht abgeneigt sind Module von Drittanbietern, könnten Sie die fastnumbers Modul überprüfen. Es bietet eine Funktion namens fast_real das genau das tut, was diese Frage fordern und tut es schneller als eine reine Python-Implementierung:

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

Benutzer codelogic und harley korrekt sind, aber denken Sie daran, wenn Sie die Zeichenfolge eine ganze Zahl kennen (zum Beispiel 545), können Sie int nennen ( "545" ), ohne zuerst Gießen zu schweben.

Wenn Sie die Saiten in einer Liste sind, können Sie die Map-Funktion auch nutzen.

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

Es ist nur gut, wenn sie alle vom gleichen Typ sind.

Die Frage scheint ein wenig alt. Aber lassen Sie mich schlagen eine Funktion, parseStr, die etwas Ähnliches macht, das heißt, gibt integer oder float und wenn eine bestimmte ASCII-String nicht zu keiner von ihnen umgerechnet werden können es gibt sie unberührt. Der Code natürlich angepasst werden könnte nur das zu tun, was Sie wollen:

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

In Python, wie kann ich eine Ziffernfolge wie „545.2222“ zu seinem entsprechenden Gleitkommawert analysieren, 542.2222? Oder analysieren die Zeichenfolge "31" auf eine ganze Zahl, 31?   Ich will nur wissen, wie ein Schwimmer-String mit einem Schwimmer zu analysieren, und (separat) einen int String in einen int.

Es ist gut, dass Sie fragen, diese separat zu tun. Wenn Sie sie abmischen, können Sie sich später für Probleme Einstellung betragen. Die einfache Antwort lautet:

"545.2222" zu schweben:

>>> float("545.2222")
545.2222

"31" auf eine ganze Zahl:

>>> int("31")
31

Andere Umwandlungen, ints zu und von Streichern und Literale:

Conversions aus verschiedenen Basen, und Sie sollen die Basis im Voraus (10 ist die Standardeinstellung) kennen. Hinweis: Sie können sie mit dem Präfix, was Python erwartet für seine Literale (siehe unten) oder das Präfix entfernen:

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

Wenn Sie nicht wissen, die Basis im Voraus, aber Sie wissen, dass sie den richtigen Präfix haben, Python kann dies für Sie schließen, wenn Sie 0 als Basis übergeben:

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

nichtdezimale (d Integer) Literale aus anderen Basen

Wenn Sie Ihre Motivation Ihren eigenen Code ist eindeutig hartcodierte spezifische Werte darstellen haben, jedoch können Sie nicht von den Basen konvertieren müssen -. Sie können Python lassen tut es für Sie automatisch mit der korrekten Syntax

Sie können die apropos Präfixe verwenden, um die automatische Konvertierung auf ganze Zahlen mit folgende Literale . Diese gelten für Python 2 und 3:

Binary, Präfix 0b

>>> 0b11111
31

Octal, Präfix 0o

>>> 0o37
31

Hexadezimal, Präfix 0x

>>> 0x1f
31

Dies kann nützlich sein, wenn Binärflags beschreibt, Dateiberechtigungen in Code oder Hex-Werte für Farben - zum Beispiel, beachten Sie keine Anführungszeichen:

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

macht mehrdeutig Python 2 octals kompatibel mit Python 3

Wenn Sie sehen, eine ganze Zahl, die mit einer 0 beginnt, in Python 2, das ist (veraltet) Oktal-Syntax.

>>> 037
31

Es ist schlecht, weil es sieht aus wie sollte der Wert 37 werden. So in Python 3, es stellt sich nun eine SyntaxError:

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

Konvertieren Sie Ihre Python 2 octals zu octals, die sowohl in der 2 und 3 mit dem 0o Präfix arbeiten:

>>> 0o37
31

float("545.2222") und int(float("545.2222"))

Die YAML Parser können Ihnen helfen, herauszufinden, was Ihr Datentyp String ist. Verwenden Sie yaml.load(), und dann können Sie verwenden type(result) für Typ zu testen:

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

Ich benutze diese Funktion für die

import ast

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

Es wird die Zeichenfolge in den Typ umwandeln

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

Sie müssen berücksichtigen Runden dies richtig zu machen.

d. int (5,1) => 5      int (5.6) => 5 - falsch, sollte 6 sein, so int wir tun (5,6 + 0,5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)

Ich bin überrascht, niemand regex erwähnt, weil manchmal String vorbereitet und normalisiert vor dem Gießen auf Nummer werden müssen

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

Nutzung:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

und durch die Art und Weise, etwas zu überprüfen, haben Sie eine Nummer aus:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal

Um in Python verwenden, um den Konstruktor funtions des Typs typisiert, vorbei an die Schnur (oder was auch immer Wert, den Sie versuchen zu werfen) als Parameter.

Zum Beispiel:

>>>float("23.333")
   23.333

Hinter den Kulissen Python ruft die Objekte __float__ Methode, die einen Schwimmer Darstellung des Parameters zurückgeben sollte. Dies ist besonders leistungsfähig, wie Sie Ihre eigenen Typen (mit Klassen) definieren können mit einem __float__ Verfahren, so dass es in einen Schwimmer mit Schwimmer gegossen werden kann (myobject).

Dies ist eine korrigierte Version von https://stackoverflow.com/a/33017514/5973334

Dies wird versuchen, eine Zeichenfolge zu analysieren und entweder int oder float zurückkehren je nachdem, was die Zeichenfolge darstellt. Es könnte Parsing Ausnahmen oder ein unerwartetes Verhalten haben.

  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

Verwendung:

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

Dies ist die Art, wie ich Pythonic einfiel.

Verwendung:

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

Dies ist eine Funktion, die jede object umwandeln (nicht nur str) int oder float, basierend auf, wenn die tatsächliche Zeichenfolge geliefert sieht aus wie int oder float. Weiterhin, wenn es ein Objekt ist, die beide __float und __int__ Methoden hat, wird standardmäßig __float__ mit

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

Hier ist eine andere Interpretation Ihrer Frage (Hinweis: Es ist vage). Es ist möglich, Sie suchen etwas wie folgt aus:

def parseIntOrFloat( aString ):
    return eval( aString )

Es funktioniert wie folgt ...

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

Theoretisch gibt es eine Injection-Schwachstelle. Die Zeichenfolge könnte zum Beispiel "import os; os.abort()" sein. Ohne Hintergrund auf, wo die Schnur kommt, ist jedoch die Möglichkeit, theoretische Spekulation. Da die Frage vage ist, ist es nicht klar, ob diese Sicherheitsanfälligkeit tatsächlich vorhanden ist oder nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top