用python读取fortran无格式数组,没有numpy

时间:2016-02-10 15:33:19

标签: python binary fortran

我对Python很陌生。我试图通过使用Python读取未格式化的Fortran文件。但是,我想将读取的元素结构化为数组。我为你准备了一个样本,以帮助你理解我的问题。在下面你可以找到一个Fortran编写器,它写入三个整数,然后是一个带有三个双精度元素的行。

    program writer
    integer :: dummy,dummy2,dummy3
    double precision,dimension(3) :: dummy_double
          dummy=1
          dummy2=2
          dummy3=3
          dummy_double(1)=4.23e0
          dummy_double(2)=5.4e0
          dummy_double(3)=7.61e0

          open(100,file="binary",form="unformatted",convert="little_endian")
          write(100) dummy
          write(100) dummy2
          write(100) dummy3
          write(100) dummy_double(1:3)
          close(100)
          end

我现在想用Python读取这个文件而不使用numpy。我知道每条记录的结尾和开头的INTEGER * 4。我跳过文件开头的前4位,然后我读取第一个整数,然后跳过8位(结束+开始),依此类推。没有分隔符以相同的顺序写入,即双精度不由INTEGER * 4分隔(如果我错了,请纠正我。)。我写信给你是因为我无法读取最后一行,有3个双精度记录。我想将它们存储在comp[3]数组中。

import struct
with open("binary", "rb") as f:
#    while True:
        dummy = f.read(4)
        print "dummy=",struct.unpack('i', f.read(4))[0]
        dummy = f.read(8)
        print "dummy2=",struct.unpack('i', f.read(4))[0]
        dummy = f.read(8)
        print "dummy3=",struct.unpack('i', f.read(4))[0]
        comp = [0] * 3
        print "length=",len(comp)
        dummy = f.read(8)
        comp=struct.unpack('<d', f.read(8))[0:2]
        print "comp=",comp[0],comp[1],comp[2]

我得到的错误如下:

$carlo: python Script_Library.py
dummy= 1
dummy2= 2
dummy3= 3
length= 3
comp= 4.23000001907
Traceback (most recent call last):
  File "Script_Library.py", line 14, in <module>
    print "comp=",comp[0],comp[1],comp[2]
IndexError: tuple index out of range

正确读取整数以及第一个双精度元素。但是,它们未正确存储。你能否更正脚本中无效的部分?

2 个答案:

答案 0 :(得分:2)

由于 durasm ,问题得以解决。

我在这里报告工作代码:

program writer
integer :: dummy,dummy2,dummy3
double precision,dimension(3) :: dummy_double
          dummy=1
          dummy2=2
          dummy3=3
          dummy_double(1)=4.23e0
          dummy_double(2)=5.4e0
          dummy_double(3)=7.61e0

          open(100,file="binary",form="unformatted",convert="little_endian")
          write(100) dummy
          write(100) dummy2
          write(100) dummy3
          write(100) dummy_double(1:3)
          close(100)
end

您可以在下面找到更正后的脚本。首先,无需分配comp。然后,我们要读取三个双精度记录,相当于24 bits和三次ddd

import struct
with open("binary", "rb") as f:
        dummy = f.read(4)
        print "dummy=",struct.unpack('i', f.read(4))[0]
        dummy = f.read(8)
        print "dummy2=",struct.unpack('i', f.read(4))[0]
        dummy = f.read(8)
        print "dummy3=",struct.unpack('i', f.read(4))[0]
        dummy = f.read(8)
        comp=struct.unpack('<ddd', f.read(24))
        print "comp=",comp[0],comp[1],comp[2]

结果:

$carlo: python Script_Library.py
dummy= 1
dummy2= 2
dummy3= 3
comp= 4.23000001907 5.40000009537 7.61000013351

答案 1 :(得分:1)

我认为你的问题出在这一行:

comp=struct.unpack('<d', f.read(8))[0:2]

如果您使用[a:b]内容对列表编制索引,则会返回从ab-1的值列表:

>>> [1, 2, 3, 4][0:2]
[1, 2]

所以在这一行之后,comp是一个列表/数组,有两个值,而不是三个。因此,comp[2]将失败并且索引超出范围错误。