【问题标题】:Python Read Formatted StringPython 读取格式化字符串
【发布时间】:2011-08-18 17:38:48
【问题描述】:

我有一个文件,其中包含许多行,格式如下:

FIELD      POSITION  DATA TYPE
------------------------------
COOP ID       1-6    Character
LATITUDE     8-15    Real
LONGITUDE   17-25    Real
ELEVATION   27-32    Real
STATE       34-35    Character
NAME        37-66    Character
COMPONENT1  68-73    Character
COMPONENT2  75-80    Character
COMPONENT3  82-87    Character
UTC OFFSET  89-90    Integer

数据全部为 ASCII 格式。

一行的例子是:

011084  31.0581  -87.0547   26.0 AL BREWTON 3 SSE                  ------ ------ ------ +6

我目前的想法是我想一次读取一行中的文件,并且以某种方式将每一行分解成一个字典,以便我可以引用组件。是否有一些模块可以在 Python 中执行此操作,或者其他一些干净的方式?

谢谢!

【问题讨论】:

  • 列是否被制表符分割?
  • 据我了解,列之间可能没有划界,所以不能简单地应用 split()。
  • 这就是列出数据在字符串中的位置的原因。
  • 如果没有划定,我们怎么知道一行的一部分在第一列而不是第二列? (编辑:我不明白您在第二条评论中的意思。您要阅读的文件与您帖子中的文件不同吗?)
  • 因为@murgatroid99,第一列是1-6个字符,第二列是8-15个字符,以此类推。

标签: python io


【解决方案1】:

编辑:您仍然可以使用 struct 模块:

请参阅struct module 文档。在我看来你想使用struct.unpack()

你想要的可能是这样的:

import struct
with open("filename.txt", "r") as f:
    for line in f:
        (coop_id, lat, lon, elev, state, name, c1, c2, c3, utc_offset
         ) = struct.unpack("6sx8sx9sx6sx2sx30sx6sx6sx6sx2s", line.strip())
        (lat, lon, elev) = map(float, (lat, lon, elev))
        utc_offset = int(utc_offset)

【讨论】:

  • 对不起,数据是ASCII格式。我会澄清这个问题。
  • 顺便说一句,我没有给你投反对票。如果数据以这种方式打包,Struct 看起来可以正常工作;唉。
  • 那么你只需要以二进制模式读取文本文件并用 stuct 解压缩每一行或对每一行进行编码并解压缩生成的bytes
  • 我尝试了几次代码,我认为它假设数据本质上是非ASCII。
  • @Richard,刚刚更改了我的示例,假设所有数据都是字符串,而不是打包值。
【解决方案2】:

我想我从您的问题/cmets 中了解您在寻找什么。如果我们假设 Real、Character 和 Integer 是唯一的数据类型,那么下面的代码应该可以工作。 (我还将假设您显示的格式文件是制表符分隔的):

format = {}
types = {"Real":float, "Character":str, "Integer":int}

for line in open("format.txt", "r"):
    values = line.split("\t")
    range = values[1].split("-")
    format[values[0]]={"start":int(range[0])-1, "end":int(range[1])-1, "type":types[values[2]]}

results=[]
for line in open("filename.txt"):
    result={}
    for key in format:
        result[key]=format["type"](line[format["start"]:format["end"]])
    results.append(result)

您最终应该得到包含字典列表的结果,其中每个字典都是从格式文件中的键名到正确数据类型的数据值的映射。

【讨论】:

    【解决方案3】:

    您似乎可以相当简单地使用字符串和切片编写函数。 string[0:5] 将是第一个元素。它是否需要可扩展,或者可能是一次性的?

    【讨论】:

    • 会有许多来自不同来源的数据文件,其格式与此不同。可扩展性将是可取的。一次性编写很容易,但似乎也可能为此目的存在一个模块。
    • 我不知道,但我也有兴趣看到答案。 :)
    猜你喜欢
    • 2019-11-28
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多