8 Stimmen

Bestimmung des Typs eines Wertes, der in Python als String dargestellt wird

Wenn ich eine kommaseparierte Datei oder Zeichenkette mit dem CSV-Parser in Python lese, werden alle Elemente als Zeichenkette dargestellt, siehe Beispiel unten.

import csv
a = "1,2,3,4,5"
r = csv.reader([a])
for row in r:
    d = row

d
['1', '2', '3', '4', '5']
type(d[0])
<type 'str'>

Ich möchte für jeden Wert feststellen, ob es sich um einen String, Float, Integer oder ein Datum handelt. Wie kann ich dies in Python tun?

15voto

Nadia Alramli Punkte 105256

Sie könnten etwa so vorgehen:

from datetime import datetime

tests = [
    # (Type, Test)
    (int, int),
    (float, float),
    (datetime, lambda value: datetime.strptime(value, "%Y/%m/%d"))
]

def getType(value):
     for typ, test in tests:
         try:
             test(value)
             return typ
         except ValueError:
             continue
     # No match
     return str

>>> getType('2010/1/12')
<type 'datetime.datetime'>
>>> getType('2010.2')
<type 'float'>
>>> getType('2010')
<type 'int'>
>>> getType('2013test')
<type 'str'>

Der Schlüssel liegt in der Reihenfolge der Tests, zum Beispiel sollte der int-Test vor dem float-Test liegen. Und für Datumsangaben können Sie weitere Tests für Formate hinzufügen, die Sie unterstützen möchten, aber natürlich können Sie nicht alle möglichen Fälle abdecken.

7voto

Tendayi Mawushe Punkte 24821

Dies kann nicht auf zuverlässige Weise geschehen, und das liegt nicht an den Beschränkungen von Python oder einer anderen Programmiersprache. Ein Mensch könnte dies nicht auf vorhersehbare Weise tun, ohne zu raten und ein paar Regeln zu befolgen (gewöhnlich genannt Heuristik wenn sie in diesem Zusammenhang verwendet werden).

Also entwerfen wir zunächst ein paar Heuristiken und kodieren sie dann in Python. Folgende Dinge sind zu beachten:

  • Alle Werte sind gültige Zeichenketten, das wissen wir, denn das ist die Grundlage unseres Problems, so dass es keinen Sinn hat, dies überhaupt zu überprüfen. Wir sollten alles andere überprüfen, was wir können, was auch immer durchfällt, können wir einfach als eine Zeichenfolge verlassen.
  • Datumsangaben sind am ehesten zu überprüfen, wenn sie in vorhersehbarer Weise formatiert sind, wie z. B. [YYYY]-[MM]-[DD]. ( ISO ISO 8601 Datumsformat ) sind sie leicht von anderen Textabschnitten zu unterscheiden, die Zahlen enthalten. Wenn die Daten in einem Format sind, das nur Zahlen enthält, wie YYYYMMDD dann sind wir aufgeschmissen, da diese Daten nicht von gewöhnlichen Zahlen zu unterscheiden sind.
  • Als Nächstes werden wir uns mit Ganzzahlen beschäftigen, da alle Ganzzahlen gültige Gleitkommazahlen sind, aber nicht alle Gleitkommazahlen gültige Ganzzahlen sind. Wir könnten einfach prüfen, ob der Text Ziffern enthält (oder Ziffern und die Buchstaben A-F, wenn hexadezimale Zahlen möglich sind), in diesem Fall wird der Wert als Ganzzahl behandelt.
  • Fließkommazahlen wären die nächste Möglichkeit, da es sich um Zahlen mit einer gewissen Formatierung (Dezimalpunkt) handelt. Es ist leicht zu erkennen 3.14159265 als Fließkommazahl. Allerdings 5.0 die einfach geschrieben werden kann als 5 ist ebenfalls eine gültige Gleitkommazahl, die jedoch in den vorangegangenen Schritten abgefangen und nicht als Gleitkommazahl erkannt worden wäre, selbst wenn dies beabsichtigt gewesen wäre.
  • Alle Werte, die nicht konvertiert werden, können als Zeichenketten behandelt werden.

Aufgrund der oben erwähnten möglichen Überschneidungen ein solches System kann nie 100% zuverlässig sein . Auch jeder neue Datentyp, den Sie unterstützen müssen (z. B. komplexe Zahlen), würde eine eigene Heuristik erfordern und müsste an der am besten geeigneten Stelle in der Prüfkette platziert werden. Je wahrscheinlicher es ist, dass eine Prüfung nur dem gewünschten Datentyp entspricht, desto weiter oben in der Kette sollte sie stehen.

Die meisten der oben erwähnten Heuristiken werden von Python für uns übernommen, wir müssen nur noch entscheiden, in welcher Reihenfolge wir sie anwenden wollen:

from datetime import datetime

heuristics = (lambda value: datetime.strptime(value, "%Y-%m-%d"),
              int, float)

def convert(value):
    for type in heuristics:
        try:
            return type(value)
        except ValueError:
            continue
    # All other heuristics failed it is a string
    return value

values = ['3.14159265', '2010-01-20', '16', 'some words']

for value in values:
    converted_value = convert(value)
    print converted_value, type(converted_value)

Es wird Folgendes ausgegeben:

3.14159265 <type 'float'>
2010-01-20 00:00:00 <type 'datetime.datetime'>
16 <type 'int'>
some words <type 'str'>

2voto

Noufal Ibrahim Punkte 68934

Es gibt keine real Antwort auf diese Frage, soweit ich das beurteilen kann, da es sich nur um Zeichenketten handelt. T 1 eine Ganzzahl oder ein Float?

Ein paar Dinge fallen mir allerdings ein. Eine davon ist, eine Art Mustervergleich durchzuführen (z. B. Wenn es einen Dezimalpunkt enthält, ist es ein Float usw.). Für das Parsen/Raten von Daten können Sie versuchen este o este .

Du könntest auch versuchen, das Element in das gewünschte Element zu "gießen" und Ausnahmen abzufangen, um die anderen zu probieren. Sie können z. B. versuchen, int, wenn es fehlschlägt, versuchen float und wenn das fehlschlägt, versuchen Datum usw.

1voto

jkp Punkte 74580

Was Sie erreichen wollen, ist schwierig, weil die Typen mehrdeutig sind: "1" könnte zum Beispiel entweder ein String oder ein int sein. Auf jeden Fall könnten Sie etwas wie dieses versuchen:

  • Datumsangaben: Vermutlich haben sie ein bekanntes Format: Wenn ja, können Sie versuchen, aus der Zeitstempel-Zeichenkette eine Datetime zu instanziieren ( datetime.strptime() ) und wenn es fehlschlägt, wissen Sie, dass es sich nicht um ein Datum handelt.

  • Fließkommazahlen: Stellen Sie sicher, dass alle Zeichen entweder eine Ziffer sind und mindestens ein "." in der Zeichenfolge enthalten ist. Dann in eine Fließkommazahl umwandeln ( float(value) )

  • Ganzzahlen: Regex der Zeichenkette und Übereinstimmung der Ziffern. Vergewissern Sie sich, dass die Zeichenkette die gleiche Länge wie die Quellzeichenkette hat, und konvertieren Sie sie dann ( int(value) )

  • Wenn nichts davon funktioniert, handelt es sich um eine Zeichenkette.

1voto

mthurlin Punkte 24849

Nun das geht nicht.

Wie würden Sie entscheiden, ob "5" als Zeichenkette oder als ganze Zahl gemeint ist? Wie würden Sie entscheiden, ob "20100120" eine ganze Zahl oder ein Datum ist?

Sie können natürlich auch Vermutungen anstellen und eine Art von Parse-Reihenfolge einführen. Versuchen Sie es zunächst als Datum, dann als Float, dann als Int und schließlich als String.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X