确定在python中表示为字符串的值的类型

Iez*_*Boy 8 python csv types casting

当我在python中使用csv解析器读取逗号分隔文件或字符串时,所有项目都表示为字符串.见下面的例子.

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

我想确定每个值是否为字符串,浮点数,整数或日期.我怎么能在python中这样做?

Nad*_*mli 14

你可以这样做:

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'>
Run Code Online (Sandbox Code Playgroud)

关键是在测试顺序中,例如int测试应该在浮动测试之前.对于日期,您可以为要支持的格式添加更多测试,但显然您无法涵盖所有​​可能的情况.


Ten*_*she 7

这不能以可靠的方式完成,并且不是由于Python或任何其他编程语言的限制.如果没有猜测并遵循一些规则(在此上下文中使用时通常称为启发式),人类无法以可预测的方式执行此操作.

因此,首先设计一些启发式,然后在Python中对它们进行编码.需要考虑的事项是:

  • 所有的值都是有效的字符串,我们知道这是因为这是我们问题的基础,所以根本没有必要检查这个.我们应该检查我们能做的其他事情,只要我们可以留下一个字符串.
  • 日期是最明显的事情,如果它们以可预测的方式格式化,例如[YYYY]-[MM]-[DD].(ISO ISO 8601日期格式),它们很容易与包含数字的其他文本位区分开来.如果日期的格式只有那样的数字,YYYYMMDD那么我们就会陷入困境,因为这些日期与普通数字无法区分.
  • 接下来我们将执行整数,因为所有整数都是有效的浮点数,但并非所有浮点数都是有效的整数.我们可以检查文本是否包含数字(或数字和字母AF,如果可能是十六进制数字),在这种情况下将值视为整数.
  • 浮动将是下一个,因为它们是具有一些格式(小数点)的数字.很容易识别3.14159265为浮点数.然而5.0,它可以简单地写成5也是一个有效的浮点数,但是在前面的步骤中会被捕获,并且即使它是预期的也不会被识别为浮点数.
  • 任何未转换的值都可以视为字符串.

由于我上面提到的可能的重叠,这样的方案永远不可能100%可靠.此外,您需要支持的任何新数据类型(可能是复数)都需要自己的一组启发式算法,并且必须放在检查链中最合适的位置.检查越有可能只匹配所需的数据类型,它应该是链上面的更高位置.

现在让我们在Python中实现这一点,我上面提到的大部分启发式方法都是由Python为我们处理的,我们只需要决定应用它们的顺序:

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)
Run Code Online (Sandbox Code Playgroud)

这输出如下:

3.14159265 <type 'float'>
2010-01-20 00:00:00 <type 'datetime.datetime'>
16 <type 'int'>
some words <type 'str'>
Run Code Online (Sandbox Code Playgroud)


AJ.*_*AJ. 0

手册中:

\n\n
\n

返回一个读取器对象,该对象将迭代给定 csv 文件中的行。csvfile 可以是任何支持迭代器协议的对象,并且每次调用 next() 方法时都会返回一个字符串 xe2x80x94 文件对象和列表对象都适合。

\n
\n\n

该接口要求每次调用 next() 时都返回一个字符串。

\n