是否有一种方法可以从CSV文件中查找和设置数据类型,而无需事先指定?

2024-09-24 22:32:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我注意到一个来自Reading Data from CSV file...的用户647772的示例

data = """True,foo,1,2.3,baz
False,bar,7,9.8,qux"""
reader = csv.reader(StringIO.StringIO(data), delimiter=",")
parsed = (({'True':True}.get(row[0], False),
       row[1],
       int(row[2]),
       float(row[3]),
       row[4])
      for row in reader)
 getBackData = list(parsed)

我找不到与为“已解析”变量编写的代码相关的CSV阅读器库。如果有人能给我指出python网站中的正确文档,我将不胜感激

另外,我想知道是否有一种方法可以在运行时确定数据类型并设置解析变量的值(如上所述)。那么,如果我修改上述代码,以下实现是否“有效”:

parsed = "((row[0], int(row[1]), int(row[2]), int(row[3]), row[4], row[5]) for row in rawReader)"

getBackData = list(eval((parsed)))

还是有更好的办法


Tags: csv代码infalsetruefordataparsed
1条回答
网友
1楼 · 发布于 2024-09-24 22:32:43

parsed变量对csv.reader并不是特别的(没有CSV读取器库,csv是Python std库中的一个模块)。此语法是Python generator expression。虽然这段代码有效,但在试图说明一个概念时,将多个概念压缩成一个语句并不总是最好的

此代码的一种更适合初学者的形式可能如下所示:

reader = csv.reader(StringIO.StringIO(data), delimiter=",")

# use a conventional for loop to build up the getBackData list
getBackData = []
for row in reader:
    converted_row = (
        row[0] == 'True',
        row[1],
        int(row[2]),
        float(row[3]),
        row[4],
        )
    getBackData.append(converted_row)

更干净的方法是将所有这些转换器推入convert_row函数,然后使用列表构建getBackData

def convert_row(raw):
    return (
        raw[0] == 'True',
        raw[1],
        int(raw[2]),
        float(raw[3]),
        raw[4],
        )

reader = csv.reader(StringIO.StringIO(data), delimiter=",")
getBackData = [convert_row(row) for row in reader]

然后您可以随意修改convert_row函数,但是readergetBackData结构保持不变

编辑:获取类型(没有经过很好的测试,但这就是想法)

def try_bool(s):
    # will convert strings "True" and "False" to bools,
    # and raise an exception otherwise
    try:
        return {"True": True, "False": False}[s]
    except KeyError:
        raise ValueError("{!r} is not a valid bool".format(s))

def get_column_types(raw):
    types = []
    for col in raw:
        for test_type in (int, float, try_bool, str):
            try:
                test_type(col)
            except ValueError:
                # fail! not data of this type
                pass
            else:
                # it worked! add test_type to list of converters
                types.append(test_type)
                break
    return types

# read the first row and get the types of each column
first_row = next(csv.reader(input_file))
col_types = get_column_types(first_row)

# now create a list of new rows with converted data items
converted = []
for row in csv.reader(input_file):
    # use zip to walk list of converters and list of columns at the same time
    converted_row = [converter(raw_value)
                         for converter, raw_value in zip(col_types, row)]
    converted.append(converted_row)

相关问题 更多 >