python - 将文件指针倒回到上一行的开头

标签 python file seek

我正在进行文本处理并使用“readline()”函数,如下所示:

ifd = open(...)
for line in ifd:
   while (condition)
         do something...
         line = ifd.readline()
         condition = ....

#这里,当条件变为假时,我需要倒回指针,以便“for”循环再次读取同一行。

ifd.fseek() 后跟 readline 给了我一个 '\n' 字符。如何倒带指针以便再次读取整行。

>>> ifd.seek(-1,1)
>>> line = ifd.readline()
>>> line
'\n'

这是我的代码

labtestnames = sorted(tmp)
#Now read each line in the inFile and write into outFile
ifd = open(inFile, "r")
ofd = open(outFile, "w")
#read the header
header = ifd.readline() #Do nothing with this line. Skip
#Write header into the output file
nl = "mrn\tspecimen_id\tlab_number\tlogin_dt\tfluid"
offset = len(nl.split("\t"))
nl = nl + "\t" + "\t".join(labtestnames)
ofd.write(nl+"\n")
lenFields = len(nl.split("\t"))


print "Reading the input file and converting into modified file for further processing (correlation analysis etc..)"

prevTup = (0,0,0)
rowComplete = 0
k=0
for line in ifd:
    k=k+1
    if (k==200): break

    items = line.rstrip("\n").split("\t")
    if((items[0] =='')):
        continue
    newline= list('' for i in range(lenFields))
    newline[0],newline[1],newline[3],newline[2],newline[4] = items[0], items[1], items[3], items[2], items[4]
    ltests = []
    ltvals = []
    while(cmp(prevTup, (items[0], items[1], items[3])) == 0): # If the same mrn, lab_number and specimen_id then fill the same row. else create a new row.
        ltests.append(items[6])
        ltvals.append(items[7])
        pos = ifd.tell()
        line = ifd.readline()
        prevTup = (items[0], items[1], items[3])
        items = line.rstrip("\n").split("\t")
        rowComplete = 1

    if (rowComplete == 1): #If the row is completed, prepare newline and write into outfile
        indices = [labtestnames.index(x) for x in ltests]
        j=0
        ifd.seek(pos)
        for i in indices:
            newline[i+offset] = ltvals[j]
            j=j+1

    if (rowComplete == 0): # 
        currTup = (items[0], items[1], items[3])
        ltests = items[6]
        ltvals = items[7]
        pos = ifd.tell()
        line = ifd.readline()
        items = line.rstrip("\n").split("\t")
        newTup = (items[0], items[1], items[3])
        if(cmp(currTup, newTup) == 0):
            prevTup = currTup
            ifd.seek(pos)
            continue
        else:
            indices = labtestnames.index(ltests)
            newline[indices+offset] = ltvals

    ofd.write(newline+"\n")

最佳答案

可以使用 itertools.groupby 更简单地处理该问题. groupby可以聚类处理相同 mrn、specimen_id 和 lab_num 的所有连续行。

执行此操作的代码是

for key, group in IT.groupby(reader, key = mykey):

哪里reader遍历输入文件的行,mykey定义为

def mykey(row):
    return (row['mrn'], row['specimen_id'], row['lab_num'])

来自 reader 的每一行传递给 mykey , 并且具有相同键的所有行聚集在同一个 group 中.


当我们这样做时,我们不妨使用 csv module将每一行读入字典(我称之为 row )。这使我们不必处理像 line.rstrip("\n").split("\t") 这样的低级字符串操作。而不是通过索引号(例如 row[3] )引用列,我们可以编写用更高级别的术语说话的代码,例如 row['lab_num'] .


import itertools as IT
import csv

inFile = 'curious.dat'
outFile = 'curious.out'

def mykey(row):
    return (row['mrn'], row['specimen_id'], row['lab_num'])

fieldnames = 'mrn specimen_id date    lab_num Bilirubin   Lipase  Calcium Magnesium   Phosphate'.split()

with open(inFile, 'rb') as ifd:
    reader = csv.DictReader(ifd, delimiter = '\t')
    with open(outFile, 'wb') as ofd:
        writer = csv.DictWriter(
            ofd, fieldnames, delimiter = '\t', lineterminator = '\n', )
        writer.writeheader()
        for key, group in IT.groupby(reader, key = mykey):
            new = {}
            row = next(group)
            for key in ('mrn', 'specimen_id', 'date', 'lab_num'):
                new[key] = row[key]
                new[row['labtest']] = row['result_val']                
            for row in group:
                new[row['labtest']] = row['result_val']
            writer.writerow(new)

产量

mrn specimen_id date    lab_num Bilirubin   Lipase  Calcium Magnesium   Phosphate
4419529 1614487 26.2675 5802791G    0.1             
3319529 1614487 26.2675 5802791G    0.3 153 8.1 2.1 4
5713871 682571  56.0779 9732266E                    4.1

关于python - 将文件指针倒回到上一行的开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13477597/

相关文章:

php - 从命令行运行脚本和使用 PHP 从 exec() 运行脚本有什么区别?

python - 为什么 sympy.simplify 会改变随机状态

file - 无需回车即可读取 Gideros 上的行

file - 如何检查文件是否存在于 makefile 中

python - 查找操作的基数是否会影响其运行速度,或者只是计算某些标准偏移量的方式?

python - SymPy 矩阵列表的总和

python - Matplotlib表格图,如何在图形和表格之间添加间隙

android - 文件模式 '*.psd'(来自 'bundled' 插件)被 'Adobe Photoshop' 插件重新分配给文件类型 'Android'

c - 如何寻找到文件末尾来确定文件大小?

python - f.seek() 和 f.tell() 读取文本文件的每一行